Skip to content

Not legal advice

dpdpkit is software that helps you implement obligations under India's Digital Personal Data Protection Act, 2023 and the DPDP Rules, 2025. It does not provide legal advice and does not guarantee compliance.

Storage

repository

Storage interface. Each adapter implements Repository with its ORM.

Rules for implementers:

  • Only the models in dpdpkit.models cross this boundary — never ORM rows.
  • Ledger and audit tables are append-only. append_* must raise SequenceConflict when (tenant_id, seq) already exists.
  • Datetimes must round-trip with microsecond precision; naive values are read back as UTC.
  • transaction() groups an audit entry with the state change it describes.

Repository

Bases: Protocol

transaction

transaction() -> AbstractContextManager[None]
append_consent_event(event: ConsentEvent) -> None
last_consent_event(tenant_id: str) -> ConsentEvent | None
latest_consent_event(tenant_id: str, principal: str, purpose: str) -> ConsentEvent | None
list_consent_events(tenant_id: str, *, principal: str | None = None, after_seq: int = 0, limit: int | None = None) -> list[ConsentEvent]

append_audit

append_audit(entry: AuditEntry) -> None

last_audit

last_audit(tenant_id: str) -> AuditEntry | None

list_audit

list_audit(tenant_id: str, *, subject_id: str | None = None, after_seq: int = 0, limit: int | None = None) -> list[AuditEntry]

save_notice

save_notice(notice: Notice) -> None

list_notices

list_notices(tenant_id: str, *, version: int | None = None) -> list[Notice]

save_request

save_request(req: RightsRequest) -> None

get_request

get_request(tenant_id: str, request_id: str) -> RightsRequest | None

list_requests

list_requests(tenant_id: str, *, principal: str | None = None, statuses: Collection[RequestStatus] | None = None) -> list[RightsRequest]

save_nominee

save_nominee(nominee: Nominee) -> None

list_nominees

list_nominees(tenant_id: str, principal: str) -> list[Nominee]

save_schedule

save_schedule(schedule: ErasureSchedule) -> None

get_schedule

get_schedule(tenant_id: str, schedule_id: str) -> ErasureSchedule | None

list_schedules

list_schedules(tenant_id: str, *, principal: str | None = None, statuses: Collection[ScheduleStatus] | None = None) -> list[ErasureSchedule]

due_erasures

due_erasures(tenant_id: str, now: datetime) -> Iterable[ErasureSchedule]

save_hold

save_hold(hold: LegalHold) -> None

list_holds

list_holds(tenant_id: str, *, principal: str | None = None, active_only: bool = True) -> list[LegalHold]

record_activity

record_activity(tenant_id: str, principal: str, at: datetime) -> None

last_activity

last_activity(tenant_id: str, principal: str) -> datetime | None

save_delivery

save_delivery(receipt: DeliveryReceipt) -> None

get_delivery

get_delivery(tenant_id: str, receipt_id: str) -> DeliveryReceipt | None

InMemoryRepository

InMemoryRepository()

Thread-safe in-memory repository for tests, examples and scripts. Not durable.

consent_events instance-attribute

consent_events: list[ConsentEvent] = []

audit instance-attribute

audit: list[AuditEntry] = []

notices instance-attribute

notices: list[Notice] = []

requests instance-attribute

requests: dict[str, RightsRequest] = {}

nominees instance-attribute

nominees: dict[str, Nominee] = {}

schedules instance-attribute

schedules: dict[str, ErasureSchedule] = {}

holds instance-attribute

holds: dict[str, LegalHold] = {}

activity instance-attribute

activity: dict[tuple[str, str], datetime] = {}

deliveries instance-attribute

deliveries: dict[str, DeliveryReceipt] = {}

transaction

transaction() -> Iterator[None]
append_consent_event(event: ConsentEvent) -> None
last_consent_event(tenant_id: str) -> ConsentEvent | None
latest_consent_event(tenant_id: str, principal: str, purpose: str) -> ConsentEvent | None
list_consent_events(tenant_id: str, *, principal: str | None = None, after_seq: int = 0, limit: int | None = None) -> list[ConsentEvent]

append_audit

append_audit(entry: AuditEntry) -> None

last_audit

last_audit(tenant_id: str) -> AuditEntry | None

list_audit

list_audit(tenant_id: str, *, subject_id: str | None = None, after_seq: int = 0, limit: int | None = None) -> list[AuditEntry]

save_notice

save_notice(notice: Notice) -> None

list_notices

list_notices(tenant_id: str, *, version: int | None = None) -> list[Notice]

save_request

save_request(req: RightsRequest) -> None

get_request

get_request(tenant_id: str, request_id: str) -> RightsRequest | None

list_requests

list_requests(tenant_id: str, *, principal: str | None = None, statuses: Collection[RequestStatus] | None = None) -> list[RightsRequest]

save_nominee

save_nominee(nominee: Nominee) -> None

list_nominees

list_nominees(tenant_id: str, principal: str) -> list[Nominee]

save_schedule

save_schedule(schedule: ErasureSchedule) -> None

get_schedule

get_schedule(tenant_id: str, schedule_id: str) -> ErasureSchedule | None

list_schedules

list_schedules(tenant_id: str, *, principal: str | None = None, statuses: Collection[ScheduleStatus] | None = None) -> list[ErasureSchedule]

due_erasures

due_erasures(tenant_id: str, now: datetime) -> list[ErasureSchedule]

save_hold

save_hold(hold: LegalHold) -> None

list_holds

list_holds(tenant_id: str, *, principal: str | None = None, active_only: bool = True) -> list[LegalHold]

record_activity

record_activity(tenant_id: str, principal: str, at: datetime) -> None

last_activity

last_activity(tenant_id: str, principal: str) -> datetime | None

save_delivery

save_delivery(receipt: DeliveryReceipt) -> None

get_delivery

get_delivery(tenant_id: str, receipt_id: str) -> DeliveryReceipt | None