Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
4f4451e
fix(toolbar): hide feedback panel when submit feedback form opens (#7…
aliu39 Jul 23, 2024
078c9f0
feat(query-builder): Add config for disabling wildcard tokens (#74678)
malwilley Jul 23, 2024
bff71c4
feat(seer-priority): Add a temporary feature flag to control seer-bas…
snigdhas Jul 23, 2024
568c329
feat(data-secrecy): Migration to Add `prevent_superuser_access` Bit F…
iamrajjoshi Jul 23, 2024
2f0a938
chore(similarity): Add re-queue for backfill task when worker is kill…
jangjodi Jul 23, 2024
1c3a348
feat(saml2): Implement SP-initiated Single Logout (#74711)
leedongwei Jul 23, 2024
5694687
Still display tokens used if no token cost metric has been sent (#74742)
colin-sentry Jul 23, 2024
11e8424
ref(replay): refactor replayerStepper calls to be memoized (#74606)
michellewzhang Jul 23, 2024
adfb52c
feat(query-builder): Add config for disallowing free text (#74752)
malwilley Jul 23, 2024
cff5483
fix(hybrid-cloud): Fix private field for RpcOrganization model (#74748)
dashed Jul 23, 2024
4cc5752
Revert "feat(seer-priority): Add a temporary feature flag to control …
getsentry-bot Jul 23, 2024
f1c4de5
feat(new-trace): Fixing Typerror from cacheMetrics being null. (#74778)
Abdkhan14 Jul 23, 2024
b7e035b
fix(utils): Specify redis cluster to use for circuit breaker rate lim…
lobsterkatie Jul 23, 2024
82af6a3
chore(spans): Fix typo in aggregate spans banner (#74767)
lobsterkatie Jul 23, 2024
21289b7
fix(context): Hide profile, replay and trace buttons on issue details…
leeandher Jul 23, 2024
21ace08
Remove extra commas from the pipelines table (#74783)
colin-sentry Jul 23, 2024
9213703
feat(toolbar): add linkout to gh code search from feature flag panel …
michellewzhang Jul 23, 2024
ab9e0e3
feat(query-builder): Add disallowUnsupportedFilters config option (#7…
malwilley Jul 23, 2024
83f711a
chore(relocation): Improve CODEOWNERS (#74762)
azaslavsky Jul 23, 2024
55215ce
feat(issue-details): Updated event navigation (#74466)
roggenkemper Jul 23, 2024
73390a2
fix(relocation): Better organization fork endpoint errors (#74784)
azaslavsky Jul 23, 2024
8d54097
feat(toolbar): Add a badge showing the number of active alerts (#74791)
ryan953 Jul 23, 2024
bc2fe88
feat(issue-search): Add metrics for new snuba search (#74741)
snigdhas Jul 23, 2024
2190378
feat(issue-search): Remove required URL param (#74685)
snigdhas Jul 23, 2024
7f1026a
feat(query-builder): Modify invalid filter styles (#74790)
malwilley Jul 23, 2024
fc6d859
Revert "chore(similarity): Add re-queue for backfill task when worker…
getsentry-bot Jul 23, 2024
a684012
ref: generated Enum type variables must match name (#74799)
asottile-sentry Jul 23, 2024
59a0547
ref: remove erroneously overridden do_request (#74800)
asottile-sentry Jul 23, 2024
25e3c5f
fix(replay): Remove browser from table if all mobile replays (#74796)
c298lee Jul 23, 2024
4197a5e
ref: match signature of create_event in test_post_process (#74804)
asottile-sentry Jul 23, 2024
5194fd1
ref: fix shadowing of make_request in tests (#74801)
asottile-sentry Jul 23, 2024
3450986
ref: prevent clobbering create_integration in base class (#74809)
asottile-sentry Jul 23, 2024
f568d6d
chore(login): update the login banners (#74789)
pevensentry Jul 24, 2024
ae533db
fix(metrics): Polish new styles (#74724)
priscilawebdev Jul 24, 2024
e6c1468
fix(metrics): Fix formula not working (#74718)
priscilawebdev Jul 24, 2024
6de2850
feat(dart): add dart raw stacktrace representation (#74715)
buenaflor Jul 24, 2024
3e81cf8
feat(metrics): span metrics open in traces (#74829)
obostjancic Jul 24, 2024
397a5ad
feat(lookup-field) Add custom lookup field `element_contains` for Arr…
vgrozdanic Jul 24, 2024
86c6bcb
ref(onboarding): Sort platform list alphabetically (#74832)
priscilawebdev Jul 24, 2024
a4bc7c3
fix(getting-started): Add missing Node SDK import to verification sni…
Lms24 Jul 24, 2024
6ecdb70
fix(metrics): Only show uppercase if rows>1 (#74836)
priscilawebdev Jul 24, 2024
cad8ea3
fix(metrics): Remove colon when single value (#74837)
priscilawebdev Jul 24, 2024
9002fcb
fix(onboarding): Add 'other' platform to all platforms list (#74838)
priscilawebdev Jul 24, 2024
f94da86
ref: unify the signature of Interface.to_string (#74798)
asottile-sentry Jul 24, 2024
a745187
ref: use baseclass implementation of monitor creation (#74806)
asottile-sentry Jul 24, 2024
9261122
ref: unify get_actions signature (#74803)
asottile-sentry Jul 24, 2024
1bb6a50
Revert "ref(seer grouping): Use new `CircuitBreaker` class for circui…
getsentry-bot Jul 24, 2024
825da45
ref: match signatures in mocked bigtable implementation (#74805)
asottile-sentry Jul 24, 2024
6429634
fix(tracing): do not reparent under span if it was never a parent (#7…
JonasBa Jul 24, 2024
815e565
ref: adjust typing so rate_limits can be a callable (#74807)
asottile-sentry Jul 24, 2024
e0acd95
feat(profiling): Add setting to enable continuous profiling (#74676)
Zylphrex Jul 24, 2024
2c4f024
chore: disable profiling for .NET (#74654)
bitsandfoxes Jul 24, 2024
6b84f16
feat(dashboards): Default widget split decision to errors (#74723)
narsaynorath Jul 24, 2024
6e76430
ref: add threadId to continuous profile link (#74730)
JonasBa Jul 24, 2024
57b2cc2
ref(metrics): Add deprecated tag and other updates (#74843)
priscilawebdev Jul 24, 2024
b123e46
fix(metrics): check for queries length and not series for uppercase (…
priscilawebdev Jul 24, 2024
0a5744b
feat(api): Document dashboard details endpoint (#74385)
narsaynorath Jul 24, 2024
6065a6d
ref/fix: more robust signature verification (#74541)
mdtro Jul 24, 2024
a9de22b
Revert "ref: add threadId to continuous profile link (#74730)"
getsentry-bot Jul 24, 2024
39e7488
ref(snubaparams): Move spans perf to SnubaParams (#74651)
wmak Jul 24, 2024
8fb9a67
chore(deps): bump django from 5.0.6 to 5.0.7 (#74662)
dependabot[bot] Jul 24, 2024
571bb58
feat(security): allow custom `salt` value in `utils.signing` (#74839)
oioki Jul 24, 2024
1a4ad42
fix: link to threadId from continuous profile link (#74848)
JonasBa Jul 24, 2024
22f1697
fix(trace) limit view to a min value (#74844)
JonasBa Jul 24, 2024
62e0909
fix(discover): Handle project.name alias (#74849)
wmak Jul 24, 2024
3692008
ref: prevent database calls at the module via mypy (#74840)
asottile-sentry Jul 24, 2024
d8cc8c0
feat(insights): project selection tooltip (#74653)
DominikB2014 Jul 24, 2024
8e9093c
feat(query-builder): Add ability to customize invalid token messages …
malwilley Jul 24, 2024
680965d
fix(query-builder): Correctly place selection background behind only …
malwilley Jul 24, 2024
b3fb6cd
Make sure end_timestamp_precise and organization_id are sent to snuba…
colin-sentry Jul 24, 2024
bef124f
chore(deps): bump setuptools from 68.2.2 to 70.0.0 (#74661)
dependabot[bot] Jul 24, 2024
5a52033
ref: add threadId to profile link and initialize the profile to threa…
JonasBa Jul 24, 2024
2663e8f
ref(tags): Update tag key-value request to use new dataset param (#74…
MichaelSun48 Jul 24, 2024
be18d81
fix(hybrid-cloud): Adds defaults to provisioning model fields, lost_p…
GabeVillalobos Jul 24, 2024
53c127c
feat(autofix): Add status check for autofix runs and log an error if …
jennmueng Jul 24, 2024
13e70f9
feat(discover): Set query source as user if flag is enabled (#74859)
shruthilayaj Jul 24, 2024
552a8ed
chore(slack): Add Use SDK Client for Spike Protection (#74810)
iamrajjoshi Jul 24, 2024
27ff5a9
fix(query-builder): Better support for adding filter keys by typing (…
malwilley Jul 24, 2024
aa92d5e
fix(issues): Parameterize multi-second durations (#74818)
mrduncan Jul 24, 2024
553e532
feat(uptime): Add stats to uptime detector code (#74814)
wedamija Jul 24, 2024
8163319
ref: fix incorrect signature of setUp for SCIMTestCase (#74858)
asottile-sentry Jul 24, 2024
f2c0b4c
chore(similarity): Add metrics for record delete call (#74759)
jangjodi Jul 24, 2024
e0fcb54
feat(anomaly detection): Send subscription update data to Seer (#74522)
mifu67 Jul 24, 2024
a299462
feat(issue-priority): Add flag for seer-based-priority (#74820)
snigdhas Jul 24, 2024
ecc0096
ref: fix serialize method in serializers.test_base (#74857)
asottile-sentry Jul 24, 2024
b4b80b1
ref(seer grouping): Consider half-snipped lines snipped for stacktrac…
lobsterkatie Jul 24, 2024
ffb2e65
ref: fix some various test mypy errors in mypy 1.11 (#74853)
asottile-sentry Jul 24, 2024
bbc2911
feat(query-builder): Add more information to the storybook page (#74866)
malwilley Jul 24, 2024
e3dcadd
ref: match signature of feature handler has (#74856)
asottile-sentry Jul 24, 2024
423b806
ref: match signature of run_test in test_slack (#74855)
asottile-sentry Jul 24, 2024
a3bef0c
feat(discover): Add top-n support for errors dataset (#74761)
shruthilayaj Jul 24, 2024
3ebf740
feat(discover): Show the banner if forced split decision (#74863)
shruthilayaj Jul 24, 2024
d5a3517
fix(issue-stream): Fix styling on priority button (#74875)
roggenkemper Jul 24, 2024
9f7fb0e
fix(conditions): Include generic groups in result mapping (#74816)
schew2381 Jul 24, 2024
bb82492
Revert "fix(hybrid-cloud): Adds defaults to provisioning model fields…
getsentry-bot Jul 24, 2024
7d03c36
feat(uptime): Add function to count number of uptime monitors active …
wedamija Jul 24, 2024
81988ef
ref: unify signature of get_annotations (#74870)
asottile-sentry Jul 24, 2024
ba12ff0
chore(processing): Add error for large num of groups (#74877)
schew2381 Jul 24, 2024
f65b4f3
ref: unify signature of get_configure_plugin_fields (#74871)
asottile-sentry Jul 24, 2024
be5e515
ref(grouping): Strip querystrings from stacktrace filenames (#74825)
lobsterkatie Jul 24, 2024
b90acda
feat(uptime): Enforce a basic quota of 1 uptime monitor per organizat…
wedamija Jul 24, 2024
7c43ffb
fix(insights): Improve readout ribbon wrapping (#74726)
gggritso Jul 24, 2024
02066d4
analytics(replay): track render of missing replay alert (#74865)
michellewzhang Jul 24, 2024
ae57e2a
fix(feedback): fix copy url (#74874)
michellewzhang Jul 24, 2024
e0aab4b
ref(feedback): add visualization for non-image attachments and allow …
michellewzhang Jul 24, 2024
ae19607
ref(similarity): Add retries with backoff to seer call in backfill (#…
jangjodi Jul 24, 2024
caa6473
ref: avoid clobbering base class do_request (#74881)
asottile-sentry Jul 24, 2024
5b8bf56
fix(hybrid-cloud): Resubmission: adds defaults to provisioning model …
GabeVillalobos Jul 24, 2024
aa70778
ref(breadcrumbs): Address early feedback (#74785)
leeandher Jul 24, 2024
7b27718
feat(onboarding): create messaging integration picker modal (#74650)
ameliahsu Jul 24, 2024
a6f413d
chore(seer grouping): Collect metric on HTML stacktraces (#74827)
lobsterkatie Jul 24, 2024
f639f73
ref: use base factories create_environment (#74882)
asottile-sentry Jul 24, 2024
de49a91
Copy tabs dir to draggableTabs dir
Jun 24, 2024
67febcf
feat(<DraggableTabs>): Add new draggable tabs component to storybook …
MichaelSun48 Jun 28, 2024
49d178f
Add query count badge and dropdown menu button
Jun 28, 2024
0eda4d6
Update baseTab component with new designs (will need to be decoupled
Jun 28, 2024
dd76bae
Fix minor unused variable errors
Jun 28, 2024
6037ea3
Add newVariant to tabs component
Jun 28, 2024
bcc1fab
Add 'Add View' button and tab dividers
Jun 28, 2024
d0b0694
Separate sections for tab menu options, revert change to dropdownmenu…
Jun 28, 2024
678c721
Add styles for temp tab, fix text baseline changing on selection stat…
Jul 1, 2024
8d70df5
Use framer motion for dragging animations. Implement some more functi…
Jul 2, 2024
0744aa9
Minor style changes
Jul 2, 2024
094ff3e
Fix tab divider left of Add View not showing up when temp view selected
Jul 2, 2024
2a7ed44
Fix menu options for temporary tabs
Jul 2, 2024
d09858e
Turn iconAdd into styled component
Jul 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
23 changes: 13 additions & 10 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,26 @@ Makefile @getsentry/owners-sentr
/bin/react-to-product-owners-yml-changes.sh @getsentry/open-source
/static/app/components/sidebar/index.tsx @getsentry/open-source

## Backup - getsentry/team-ospo#153
/src/sentry/backup/ @getsentry/open-source
/src/sentry/runner/commands/backup.py @getsentry/open-source
/src/sentry/testutils/helpers/backups.py @getsentry/open-source
/tests/sentry/backup/ @getsentry/open-source
/tests/sentry/runner/commands/test_backup.py @getsentry/open-source

## Relocation - getsentry/team-ospo#153
/src/sentry/analytics/events/relocation_created.py @getsentry/open-source
/src/sentry/analytics/events/relocation_forked.py @getsentry/open-source
/src/sentry/analytics/events/relocation_organization_imported.py @getsentry/open-source
/src/sentry/analytics/events/relocation_*.py @getsentry/open-source
/src/sentry/api/endpoints/organization_fork.py @getsentry/open-source
/src/sentry/api/endpoints/relocation/ @getsentry/open-source
/src/sentry/backup/ @getsentry/open-source
/src/sentry/backup/services/import_export/ @getsentry/open-source
/src/sentry/backup/services/relocation_export/ @getsentry/open-source
/src/sentry/runner/commands/backup.py @getsentry/open-source
/src/sentry/api/serialiers/models/relocation/ @getsentry/open-source
/src/sentry/models/relocation/ @getsentry/open-source
/src/sentry/relocation/ @getsentry/open-source
/src/sentry/tasks/relocation.py @getsentry/open-source
/src/sentry/testutils/helpers/backups.py @getsentry/open-source
/src/sentry/utils/relocation.py @getsentry/open-source
/tests/sentry/api/endpoints/relocation @getsentry/open-source
/tests/sentry/backup/ @getsentry/open-source
/tests/sentry/api/endpoints/test_organization_fork.py @getsentry/open-source
/tests/sentry/api/serializer/test_relocation.py @getsentry/open-source
/tests/sentry/tasks/test_relocation.py @getsentry/open-source
/tests/sentry/runner/commands/test_backup.py @getsentry/open-source
/tests/sentry/utils/test_relocation.py @getsentry/open-source

## Build & Releases
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ jobs:
python3 -m tools.fast_editable --path .
sentry init

- run: mypy
- run: PYTHONWARNINGS=error::RuntimeWarning mypy
id: run

- uses: getsentry/action-github-app-token@d4b5da6c5e37703f8c3b3e43abb5705b46e159cc # v3.0.0
Expand Down
2 changes: 1 addition & 1 deletion migrations_lockfile.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ hybridcloud: 0016_add_control_cacheversion
nodestore: 0002_nodestore_no_dictfield
remote_subscriptions: 0003_drop_remote_subscription
replays: 0004_index_together
sentry: 0744_add_dataset_source_field_to_dashboards
sentry: 0745_add_prevent_superuser_access_bitflag
social_auth: 0002_default_auto_field
uptime: 0006_projectuptimesubscription_name_owner
4 changes: 2 additions & 2 deletions requirements-dev-frozen.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ cssutils==2.9.0
datadog==0.49.1
distlib==0.3.8
distro==1.8.0
django==5.0.6
django==5.0.7
django-crispy-forms==1.14.0
django-csp==3.8
django-pg-zero-downtime-migrations==0.13
Expand Down Expand Up @@ -245,4 +245,4 @@ zstandard==0.18.0

# The following packages are considered to be unsafe in a requirements file:
pip==23.3.1
setuptools==68.2.2
setuptools==70.0.0
4 changes: 2 additions & 2 deletions requirements-frozen.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ cssselect==1.0.3
cssutils==2.9.0
datadog==0.49.1
distro==1.8.0
django==5.0.6
django==5.0.7
django-crispy-forms==1.14.0
django-csp==3.8
django-pg-zero-downtime-migrations==0.13
Expand Down Expand Up @@ -156,4 +156,4 @@ xmlsec==1.3.13
zstandard==0.18.0

# The following packages are considered to be unsafe in a requirements file:
setuptools==68.2.2
setuptools==70.0.0
4 changes: 2 additions & 2 deletions src/sentry/api/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@ class Endpoint(APIView):

owner: ApiOwner = ApiOwner.UNOWNED
publish_status: dict[HTTP_METHOD_NAME, ApiPublishStatus] = {}
rate_limits: RateLimitConfig | dict[
str, dict[RateLimitCategory, RateLimit]
rate_limits: RateLimitConfig | dict[str, dict[RateLimitCategory, RateLimit]] | Callable[
..., RateLimitConfig | dict[str, dict[RateLimitCategory, RateLimit]]
] = DEFAULT_RATE_LIMIT_CONFIG
enforce_rate_limit: bool = settings.SENTRY_RATELIMITER_ENABLED
snuba_methods: list[HTTP_METHOD_NAME] = []
Expand Down
42 changes: 24 additions & 18 deletions src/sentry/api/bases/organization_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,33 +240,39 @@ def handle_on_demand(self, request: Request) -> tuple[bool, MetricSpecType]:

return use_on_demand_metrics, on_demand_metric_type

def get_split_decision(self, has_errors, has_transactions_data):
def save_split_decision(self, widget, has_errors, has_transactions_data, organization, user):
"""This can be removed once the discover dataset has been fully split"""
source = DashboardDatasetSourcesTypes.INFERRED.value
if has_errors and not has_transactions_data:
decision = DashboardWidgetTypes.ERROR_EVENTS
sentry_sdk.set_tag("discover.split_reason", "query_result")
elif not has_errors and has_transactions_data:
decision = DashboardWidgetTypes.TRANSACTION_LIKE
elif has_errors and has_transactions_data:
decision = DashboardWidgetTypes.DISCOVER
sentry_sdk.set_tag("discover.split_reason", "query_result")
else:
# In the case that neither side has data, we do not need to split this yet and can make multiple queries to check each time.
# This will help newly created widgets or infrequent count widgets that shouldn't be prematurely assigned a side.
decision = None
sentry_sdk.set_tag("split_decision", decision)
return decision
if features.has(
"organizations:performance-discover-dataset-selector", organization, actor=user
):
# In the case that neither side has data, or both sides have data, default to errors.
decision = DashboardWidgetTypes.ERROR_EVENTS
source = DashboardDatasetSourcesTypes.FORCED.value
sentry_sdk.set_tag("discover.split_reason", "default")
else:
# This branch can be deleted once the feature flag for the discover split is removed
if has_errors and has_transactions_data:
decision = DashboardWidgetTypes.DISCOVER
else:
# In the case that neither side has data, we do not need to split this yet and can make multiple queries to check each time.
# This will help newly created widgets or infrequent count widgets that shouldn't be prematurely assigned a side.
decision = None

def save_split_decision(self, widget, has_errors, has_transactions_data):
"""This can be removed once the discover dataset has been fully split"""
new_discover_widget_split = self.get_split_decision(has_errors, has_transactions_data)
if (
new_discover_widget_split is not None
and widget.discover_widget_split != new_discover_widget_split
):
widget.discover_widget_split = new_discover_widget_split
widget.dataset_source = DashboardDatasetSourcesTypes.INFERRED.value
sentry_sdk.set_tag("discover.split_decision", decision)
if decision is not None and widget.discover_widget_split != decision:
widget.discover_widget_split = decision
widget.dataset_source = source
widget.save()

return new_discover_widget_split
return decision

def save_discover_saved_query_split_decision(
self, query, dataset_inferred_from_query, has_errors, has_transactions_data
Expand Down
3 changes: 3 additions & 0 deletions src/sentry/api/endpoints/auth_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from sentry.api.validators import AuthVerifyValidator
from sentry.api.validators.auth import MISSING_PASSWORD_OR_U2F_CODE
from sentry.auth.authenticators.u2f import U2fInterface
from sentry.auth.providers.saml2.provider import handle_saml_single_logout
from sentry.auth.services.auth.impl import promote_request_rpc_user
from sentry.auth.superuser import SUPERUSER_ORG_ID
from sentry.models.authenticator import Authenticator
Expand Down Expand Up @@ -293,6 +294,8 @@ def delete(self, request: Request, *args, **kwargs) -> Response:

Deauthenticate all active sessions for this user.
"""
handle_saml_single_logout(request)

# For signals to work here, we must promote the request.user to a full user object
logout(request._request)
request.user = AnonymousUser()
Expand Down
48 changes: 14 additions & 34 deletions src/sentry/api/endpoints/group_ai_autofix.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

import logging
from datetime import datetime
from datetime import datetime, timedelta
from typing import Any

import orjson
Expand All @@ -16,10 +16,11 @@
from sentry.api.base import region_silo_endpoint
from sentry.api.bases.group import GroupEndpoint
from sentry.api.serializers import EventSerializer, serialize
from sentry.autofix.utils import get_autofix_repos_from_project_code_mappings
from sentry.autofix.utils import get_autofix_repos_from_project_code_mappings, get_autofix_state
from sentry.models.group import Group
from sentry.models.user import User
from sentry.seer.signed_seer_api import sign_with_seer_secret
from sentry.tasks.autofix import check_autofix_status
from sentry.types.ratelimit import RateLimit, RateLimitCategory
from sentry.users.services.user.service import user_service

Expand Down Expand Up @@ -133,33 +134,7 @@ def _call_autofix(

response.raise_for_status()

def _call_get_autofix_state(self, group_id: int) -> dict[str, Any] | None:
path = "/v1/automation/autofix/state"
body = orjson.dumps(
{
"group_id": group_id,
}
)
response = requests.post(
f"{settings.SEER_AUTOFIX_URL}{path}",
data=body,
headers={
"content-type": "application/json;charset=utf-8",
**sign_with_seer_secret(
url=f"{settings.SEER_AUTOFIX_URL}{path}",
body=body,
),
},
)

response.raise_for_status()

result = response.json()

if result and result["group_id"] == group_id:
return result["state"]

return None
return response.json().get("run_id")

def post(self, request: Request, group: Group) -> Response:
data = orjson.loads(request.body)
Expand Down Expand Up @@ -203,7 +178,7 @@ def post(self, request: Request, group: Group) -> Response:
)

try:
self._call_autofix(
run_id = self._call_autofix(
request.user,
group,
repos,
Expand All @@ -226,15 +201,20 @@ def post(self, request: Request, group: Group) -> Response:
500,
)

check_autofix_status.apply_async(args=[run_id], countdown=timedelta(minutes=15).seconds)

return Response(
status=202,
)

def get(self, request: Request, group: Group) -> Response:
autofix_state = self._call_get_autofix_state(group.id)
autofix_state = get_autofix_state(group_id=group.id)

response_state: dict[str, Any] | None = None

if autofix_state:
user_ids = autofix_state.get("actor_ids", [])
response_state = autofix_state.dict()
user_ids = autofix_state.actor_ids
if user_ids:
users = user_service.serialize_many(
filter={"user_ids": user_ids, "organization_id": request.organization.id},
Expand All @@ -243,6 +223,6 @@ def get(self, request: Request, group: Group) -> Response:

users_map = {user["id"]: user for user in users}

autofix_state["users"] = users_map
response_state["users"] = users_map

return Response({"autofix": autofix_state})
return Response({"autofix": response_state})
79 changes: 51 additions & 28 deletions src/sentry/api/endpoints/organization_dashboard_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.db import IntegrityError, router, transaction
from django.db.models import F
from django.utils import timezone
from drf_spectacular.utils import extend_schema
from rest_framework.request import Request
from rest_framework.response import Response

Expand All @@ -13,7 +14,16 @@
from sentry.api.endpoints.organization_dashboards import OrganizationDashboardsPermission
from sentry.api.exceptions import ResourceDoesNotExist
from sentry.api.serializers import serialize
from sentry.api.serializers.models.dashboard import DashboardDetailsModelSerializer
from sentry.api.serializers.rest_framework import DashboardDetailsSerializer
from sentry.apidocs.constants import (
RESPONSE_BAD_REQUEST,
RESPONSE_FORBIDDEN,
RESPONSE_NO_CONTENT,
RESPONSE_NOT_FOUND,
)
from sentry.apidocs.examples.dashboard_examples import DashboardExamples
from sentry.apidocs.parameters import DashboardParams, GlobalParams
from sentry.models.dashboard import Dashboard, DashboardTombstone

EDIT_FEATURE = "organizations:dashboards-edit"
Expand Down Expand Up @@ -44,24 +54,28 @@ def _get_dashboard(self, request: Request, organization, dashboard_id):
return Dashboard.objects.get(id=dashboard_id, organization_id=organization.id)


@extend_schema(tags=["Dashboards"])
@region_silo_endpoint
class OrganizationDashboardDetailsEndpoint(OrganizationDashboardBase):
publish_status = {
"DELETE": ApiPublishStatus.UNKNOWN,
"GET": ApiPublishStatus.UNKNOWN,
"PUT": ApiPublishStatus.UNKNOWN,
"DELETE": ApiPublishStatus.PUBLIC,
"GET": ApiPublishStatus.PUBLIC,
"PUT": ApiPublishStatus.PUBLIC,
}

@extend_schema(
operation_id="Retrieve an Organization's Custom Dashboard",
parameters=[GlobalParams.ORG_ID_OR_SLUG, DashboardParams.DASHBOARD_ID],
responses={
200: DashboardDetailsModelSerializer,
403: RESPONSE_FORBIDDEN,
404: RESPONSE_NOT_FOUND,
},
examples=DashboardExamples.DASHBOARD_GET_RESPONSE,
)
def get(self, request: Request, organization, dashboard) -> Response:
"""
Retrieve an Organization's Dashboard
````````````````````````````````````

Return details on an individual organization's dashboard.

:pparam Organization organization: the organization the dashboard belongs to.
:pparam Dashboard dashboard: the dashboard object
:auth: required
Return details about an organization's custom dashboard.
"""
if not features.has(READ_FEATURE, organization, actor=request.user):
return Response(status=404)
Expand All @@ -71,17 +85,19 @@ def get(self, request: Request, organization, dashboard) -> Response:

return self.respond(serialize(dashboard, request.user))

@extend_schema(
operation_id="Delete an Organization's Custom Dashboard",
parameters=[GlobalParams.ORG_ID_OR_SLUG, DashboardParams.DASHBOARD_ID],
responses={
204: RESPONSE_NO_CONTENT,
403: RESPONSE_FORBIDDEN,
404: RESPONSE_NOT_FOUND,
},
)
def delete(self, request: Request, organization, dashboard) -> Response:
"""
Delete an Organization's Dashboard
```````````````````````````````````

Delete an individual organization's dashboard, or tombstone
Delete an organization's custom dashboard, or tombstone
a pre-built dashboard which effectively deletes it.

:pparam Organization organization: the organization the dashboard belongs to.
:pparam Dashboard dashboard: the dashboard object
:auth: required
"""
if not features.has(EDIT_FEATURE, organization, actor=request.user):
return Response(status=404)
Expand All @@ -105,17 +121,24 @@ def delete(self, request: Request, organization, dashboard) -> Response:

return self.respond(status=204)

@extend_schema(
operation_id="Edit an Organization's Custom Dashboard",
parameters=[GlobalParams.ORG_ID_OR_SLUG, DashboardParams.DASHBOARD_ID],
request=DashboardDetailsSerializer,
responses={
200: DashboardDetailsModelSerializer,
400: RESPONSE_BAD_REQUEST,
403: RESPONSE_FORBIDDEN,
404: RESPONSE_NOT_FOUND,
},
examples=DashboardExamples.DASHBOARD_PUT_RESPONSE,
)
def put(self, request: Request, organization, dashboard) -> Response:
"""
Edit an Organization's Dashboard
```````````````````````````````````

Edit an individual organization's dashboard as well as
bulk edits on widgets (i.e. rearranging widget order).

:pparam Organization organization: the organization the dashboard belongs to.
:pparam Dashboard dashboard: the old dashboard object
:auth: required
Edit an organization's custom dashboard as well as any bulk
edits on widgets that may have been made. (For example, widgets
that have been rearranged, updated queries and fields, specific
display types, and so on.)
"""
if not features.has(EDIT_FEATURE, organization, actor=request.user):
return Response(status=404)
Expand Down
Loading