Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,3 @@ omit =
src/dispatch/api.py
src/dispatch/extensions.py
src/dispatch/scheduler.py

40 changes: 32 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,31 @@
# To Skip Checks:
#
# git commit --no-verify
# git push --no-verify
# test
#
# To update all hooks automatically:
#
# pre-commit autoupdate
fail_fast: false

default_language_version:
python: python3.11.2

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: no-commit-to-branch # prevent direct commits to the `main` branch
- id: check-yaml
args: ["--unsafe"]
- id: check-toml
- id: end-of-file-fixer
- id: trailing-whitespace

- repo: https://github.com/astral-sh/ruff-pre-commit
# ruff version.
rev: v0.7.0
rev: v0.11.12
hooks:
# Run the linter.
#
Expand All @@ -26,19 +42,27 @@ repos:
# Run the formatter.
- id: ruff-format

# Typos
# typos
- repo: https://github.com/crate-ci/typos
rev: v1.26.1
rev: v1.33.1
hooks:
- id: typos
exclude: ^(data/dispatch-sample-data.dump|src/dispatch/static/dispatch/src/|src/dispatch/database/revisions/)
exclude: |
(?x)^(
src/dispatch/database/revisions/core/versions/|
src/dispatch/database/revisions/tenant/versions/|
src/dispatch/static/dispatch/src/assets/icons/|
data/dispatch-sample-data.dump|
src/dispatch/plugins/dispatch_zoom/client.py
)

# Pytest
# pytest
- repo: local
hooks:
- id: tests
name: run tests
entry: pytest -v tests/
entry: pytest -v tests
language: system
types: [python]
stages: [push]
pass_filenames: false
always_run: true
stages: [pre-push]
2 changes: 1 addition & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ RUN buildDeps="" \
&& rm -rf /var/lib/apt/lists/* \
# mjml has to be installed differently here because
# after node 14, docker will install npm files at the
# root directoy and fail, so we have to create a new
# root directory and fail, so we have to create a new
# directory and use it for the install then copy the
# files to the root directory to maintain backwards
# compatibility for email generation
Expand Down
3 changes: 2 additions & 1 deletion src/dispatch/auth/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ def create(*, db_session, organization: str, user_in: (UserRegister | UserCreate

# create the user
user = DispatchUser(
**user_in.model_dump(exclude={"password", "organizations", "projects", "role"}), password=password
**user_in.model_dump(exclude={"password", "organizations", "projects", "role"}),
password=password,
)

org = organization_service.get_by_slug_or_raise(
Expand Down
2 changes: 1 addition & 1 deletion src/dispatch/case/flows.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
send_case_rating_feedback_message,
send_case_update_notifications,
send_event_paging_message,
send_event_update_prompt_reminder
send_event_update_prompt_reminder,
)
from .models import Case
from .service import get
Expand Down
3 changes: 2 additions & 1 deletion src/dispatch/case/messaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ def send_event_update_prompt_reminder(case: Case, db_session: Session) -> None:
"text": {"type": "plain_text", "text": "Update Case"},
"action_id": CaseNotificationActions.update,
"style": "primary",
"value": button_metadata
"value": button_metadata,
}
],
},
Expand All @@ -430,6 +430,7 @@ def send_event_update_prompt_reminder(case: Case, db_session: Session) -> None:

log.debug(f"Security Event update reminder sent to {case.assignee.individual.email}.")


def send_event_paging_message(case: Case, db_session: Session, oncall_name: str) -> None:
"""
Sends a message to the case conversation channel to notify the reporter that they can engage
Expand Down
3 changes: 3 additions & 0 deletions src/dispatch/case/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ class CaseReadMinimal(CaseBase):
assignee: ParticipantReadMinimal | None = None
case_costs: list[CaseCostReadMinimal] = []


class CaseReadMinimalWithExtras(CaseBase):
"""Pydantic model for reading minimal case data."""

Expand Down Expand Up @@ -451,11 +452,13 @@ class CasePagination(Pagination):

items: list[CaseReadMinimal] = []


class CasePaginationMinimalWithExtras(Pagination):
"""Pydantic model for paginated minimal case results."""

items: list[CaseReadMinimalWithExtras] = []


class CaseExpandedPagination(Pagination):
"""Pydantic model for paginated expanded case results."""

Expand Down
3 changes: 1 addition & 2 deletions src/dispatch/case/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,7 @@ def update(*, db_session, case: Case, case_in: CaseUpdate, current_user: Dispatc
db_session=db_session,
source="Dispatch Core App",
description=(
f"Case visibility changed to {case_in.visibility.lower()} "
f"by {current_user.email}"
f"Case visibility changed to {case_in.visibility.lower()} by {current_user.email}"
),
dispatch_user_id=current_user.id,
case_id=case.id,
Expand Down
10 changes: 10 additions & 0 deletions src/dispatch/case/type/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Models for case types and related entities in the Dispatch application."""

from pydantic import field_validator, AnyHttpUrl

from sqlalchemy import JSON, Boolean, Column, ForeignKey, Integer, String
Expand All @@ -19,6 +20,7 @@

class CaseType(ProjectMixin, Base):
"""SQLAlchemy model for case types, representing different types of cases in the system."""

__table_args__ = (UniqueConstraint("name", "project_id"),)
id = Column(Integer, primary_key=True)
name = Column(String)
Expand Down Expand Up @@ -66,6 +68,7 @@ def get_meta(self, slug):
# Pydantic models
class Document(DispatchBase):
"""Pydantic model for a document related to a case type."""

id: PrimaryKey
description: str | None = None
name: NameStr
Expand All @@ -76,6 +79,7 @@ class Document(DispatchBase):

class IncidentType(DispatchBase):
"""Pydantic model for an incident type related to a case type."""

id: PrimaryKey
description: str | None = None
name: NameStr
Expand All @@ -84,6 +88,7 @@ class IncidentType(DispatchBase):

class Service(DispatchBase):
"""Pydantic model for a service related to a case type."""

id: PrimaryKey
description: str | None = None
external_id: str
Expand All @@ -94,6 +99,7 @@ class Service(DispatchBase):

class CaseTypeBase(DispatchBase):
"""Base Pydantic model for case types, used for shared fields."""

case_template_document: Document | None = None
conversation_target: str | None = None
default: bool | None = False
Expand All @@ -118,19 +124,23 @@ def replace_none_with_empty_list(cls, value):

class CaseTypeCreate(CaseTypeBase):
"""Pydantic model for creating a new case type."""

pass


class CaseTypeUpdate(CaseTypeBase):
"""Pydantic model for updating an existing case type."""

id: PrimaryKey | None = None


class CaseTypeRead(CaseTypeBase):
"""Pydantic model for reading a case type from the database."""

id: PrimaryKey


class CaseTypePagination(Pagination):
"""Pydantic model for paginated case type results."""

items: list[CaseTypeRead] = []
11 changes: 10 additions & 1 deletion src/dispatch/case/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,15 @@
case_update_flow,
get_case_participants_flow,
)
from .models import Case, CaseCreate, CaseExpandedPagination, CasePagination, CasePaginationMinimalWithExtras, CaseRead, CaseUpdate
from .models import (
Case,
CaseCreate,
CaseExpandedPagination,
CasePagination,
CasePaginationMinimalWithExtras,
CaseRead,
CaseUpdate,
)
from .service import create, delete, get, get_participants, update

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -144,6 +152,7 @@ def get_cases_minimal(

return json.loads(CasePaginationMinimalWithExtras(**pagination).json())


@router.post("", response_model=CaseRead, summary="Creates a new case.")
def create_case(
db_session: DbSession,
Expand Down
8 changes: 2 additions & 6 deletions src/dispatch/case_cost_type/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ def get(*, db_session, case_cost_type_id: int) -> CaseCostType | None:
return db_session.query(CaseCostType).filter(CaseCostType.id == case_cost_type_id).one_or_none()


def get_response_cost_type(
*, db_session, project_id: int, model_type: str
) -> CaseCostType | None:
def get_response_cost_type(*, db_session, project_id: int, model_type: str) -> CaseCostType | None:
"""Gets the default response cost type."""
return (
db_session.query(CaseCostType)
Expand Down Expand Up @@ -52,9 +50,7 @@ def get_or_create_response_cost_type(
return case_cost_type


def get_all_response_case_cost_types(
*, db_session, project_id: int
) -> list[CaseCostType | None]:
def get_all_response_case_cost_types(*, db_session, project_id: int) -> list[CaseCostType | None]:
"""Returns all response case cost types.

This function queries the database for all case cost types that are marked as the response cost type.
Expand Down
1 change: 0 additions & 1 deletion src/dispatch/conference/service.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

from .models import Conference, ConferenceCreate


Expand Down
6 changes: 6 additions & 0 deletions src/dispatch/conversation/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

class Conversation(Base, ResourceMixin):
"""SQLAlchemy model for conversation resources."""

id = Column(Integer, primary_key=True)
channel_id = Column(String)
thread_id = Column(String)
Expand All @@ -22,22 +23,26 @@ class Conversation(Base, ResourceMixin):
# Pydantic models...
class ConversationBase(ResourceBase):
"""Base Pydantic model for conversation resources."""

channel_id: str | None = None
thread_id: str | None = None


class ConversationCreate(ConversationBase):
"""Pydantic model for creating a conversation resource."""

pass


class ConversationUpdate(ConversationBase):
"""Pydantic model for updating a conversation resource."""

pass


class ConversationRead(ConversationBase):
"""Pydantic model for reading a conversation resource."""

id: PrimaryKey
description: str | None = None

Expand All @@ -50,4 +55,5 @@ def set_description(cls, _):

class ConversationNested(ConversationBase):
"""Pydantic model for a nested conversation resource."""

pass
1 change: 0 additions & 1 deletion src/dispatch/data/alert/service.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

from pydantic import ValidationError


Expand Down
18 changes: 10 additions & 8 deletions src/dispatch/data/query/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ def get_by_name_or_raise(*, db_session, query_in: QueryRead, project_id: int) ->
query = get_by_name(db_session=db_session, name=query_in.name, project_id=project_id)

if not query:
raise ValidationError([
{
"loc": ("query",),
"msg": f"Query not found: {query_in.name}",
"type": "value_error",
"input": query_in.name,
}
])
raise ValidationError(
[
{
"loc": ("query",),
"msg": f"Query not found: {query_in.name}",
"type": "value_error",
"input": query_in.name,
}
]
)

return query

Expand Down
18 changes: 10 additions & 8 deletions src/dispatch/data/source/data_format/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,16 @@ def get_by_name_or_raise(
)

if not data_format:
raise ValidationError([
{
"loc": ("dataFormat",),
"msg": f"SourceDataFormat not found: {source_data_format_in.name}",
"type": "value_error",
"input": source_data_format_in.name,
}
])
raise ValidationError(
[
{
"loc": ("dataFormat",),
"msg": f"SourceDataFormat not found: {source_data_format_in.name}",
"type": "value_error",
"input": source_data_format_in.name,
}
]
)

return data_format

Expand Down
18 changes: 10 additions & 8 deletions src/dispatch/data/source/environment/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,16 @@ def get_by_name_or_raise(
)

if not source:
raise ValidationError([
{
"loc": ("source",),
"msg": f"Source environment not found: {source_environment_in.name}",
"type": "value_error",
"input": source_environment_in.name,
}
])
raise ValidationError(
[
{
"loc": ("source",),
"msg": f"Source environment not found: {source_environment_in.name}",
"type": "value_error",
"input": source_environment_in.name,
}
]
)

return source

Expand Down
Loading
Loading