Skip to main content

Recertification

The Recertification resource (client.recertification) manages recertification cycles and audit reviews programmatically.

Methods

create_cycle(space_slug, *, name, due_date, cycle_type=, description=)

Create a new recertification cycle.

ParameterTypeDefaultDescription
space_slugstrrequiredSpace identifier
namestrrequiredCycle name
due_datestrrequiredISO-8601 due date
cycle_typestr"product""product" or "access"
descriptionstr | NoneNoneOptional description

Returns: RecertificationCycle

cycle = await client.recertification.create_cycle(
"marketing-analytics",
name="Q1 2026 PII Review",
due_date="2026-03-31T23:59:59Z",
cycle_type="product",
description="Quarterly review of PII-tagged products.",
)
print(f"Created cycle: {cycle.id}")

list_cycles(space_slug)

List all recertification cycles in a space.

ParameterTypeDescription
space_slugstrSpace identifier

Returns: list[RecertificationCycle]

cycles = await client.recertification.list_cycles("marketing-analytics")
for c in cycles:
print(f"{c.name}: {c.status} ({c.reviewed_count}/{c.audit_count})")

get_cycle(space_slug, cycle_id)

Get a cycle with all its audit items.

ParameterTypeDescription
space_slugstrSpace identifier
cycle_idUUIDCycle UUID

Returns: RecertificationCycle (with embedded audits list)

cycle = await client.recertification.get_cycle(
"marketing-analytics", cycle_id
)
for audit in cycle.audits:
print(f"{audit.resource_name}: {audit.status}")

update_config(space_slug, cycle_id, *, filters=, request_title_template=, request_description_template=)

Update the cycle's filters and request templates. All parameters are optional — only provided fields are updated.

ParameterTypeDefaultDescription
space_slugstrrequiredSpace identifier
cycle_idUUIDrequiredCycle UUID
filtersdict | NoneNoneFilter object (keys: tags, product_type, criticality)
request_title_templatestr | NoneNoneJinja2 title template
request_description_templatestr | NoneNoneJinja2 description template

Returns: RecertificationCycle

cycle = await client.recertification.update_config(
"marketing-analytics",
cycle_id,
filters={"tags": ["pii"], "criticality": ["High"]},
request_title_template="Recertify {{ product_name }}",
)

delete_cycle(space_slug, cycle_id)

Permanently delete a cycle and all its audit items.

ParameterTypeDescription
space_slugstrSpace identifier
cycle_idUUIDCycle UUID

Returns: None

await client.recertification.delete_cycle("marketing-analytics", cycle_id)

populate_cycle(space_slug, cycle_id)

Auto-populate audit items from live data. Idempotent — existing items are skipped.

ParameterTypeDescription
space_slugstrSpace identifier
cycle_idUUIDCycle UUID

Returns: PopulateResult

result = await client.recertification.populate_cycle(
"marketing-analytics", cycle_id
)
print(f"Created {result.created} audit items")

recertify_all(space_slug, cycle_id)

Create recertification requests for all pending audit items in bulk.

ParameterTypeDescription
space_slugstrSpace identifier
cycle_idUUIDCycle UUID

Returns: RecertifyAllResult

result = await client.recertification.recertify_all(
"marketing-analytics", cycle_id
)
print(f"Created {result.created} requests")

archive_cycle(space_slug, cycle_id)

Archive a cycle, hiding it from the default list view.

ParameterTypeDescription
space_slugstrSpace identifier
cycle_idUUIDCycle UUID

Returns: RecertificationCycle

await client.recertification.archive_cycle("marketing-analytics", cycle_id)

unarchive_cycle(space_slug, cycle_id)

Restore an archived cycle to the default list.

ParameterTypeDescription
space_slugstrSpace identifier
cycle_idUUIDCycle UUID

Returns: RecertificationCycle

await client.recertification.unarchive_cycle("marketing-analytics", cycle_id)

complete_cycle(space_slug, cycle_id)

Mark a cycle as completed (read-only).

ParameterTypeDescription
space_slugstrSpace identifier
cycle_idUUIDCycle UUID

Returns: RecertificationCycle

completed = await client.recertification.complete_cycle(
"marketing-analytics", cycle_id
)
print(f"Cycle status: {completed.status}")

cancel_cycle(space_slug, cycle_id)

Mark a cycle as cancelled. Can be reopened later.

ParameterTypeDescription
space_slugstrSpace identifier
cycle_idUUIDCycle UUID

Returns: RecertificationCycle

cancelled = await client.recertification.cancel_cycle(
"marketing-analytics", cycle_id
)

get_filter_suggestions(space_slug)

Get the available filter values for cycle population. Returns the distinct tags, product types, and criticalities present in the space — useful for building autocomplete UIs.

ParameterTypeDescription
space_slugstrSpace identifier

Returns: FilterSuggestions

suggestions = await client.recertification.get_filter_suggestions(
"marketing-analytics"
)
print(f"Tags: {suggestions.tags}")
print(f"Types: {suggestions.product_types}")
print(f"Criticalities: {suggestions.criticalities}")

review_audit(audit_id, *, status, comments=)

Approve or reject an audit item.

ParameterTypeDefaultDescription
audit_idUUIDrequiredAudit UUID
statusstrrequired"approved" or "rejected"
commentsstr | NoneNoneOptional reviewer notes

Returns: RecertificationAudit

audit = await client.recertification.review_audit(
audit_id,
status="approved",
comments="Access confirmed for ongoing reporting.",
)
print(f"Audit {audit.id}: {audit.status}")

create_audit_request(space_slug, audit_id)

Create a recertification request for a single audit item. The request is routed through the cycle's configured workflow.

ParameterTypeDescription
space_slugstrSpace identifier
audit_idUUIDAudit UUID

Returns: RecertificationAudit (with request_id populated)

audit = await client.recertification.create_audit_request(
"marketing-analytics", audit_id
)
print(f"Request created: {audit.request_id}")

Models

RecertificationCycle

FieldTypeDescription
idUUIDCycle identifier
namestrCycle name
descriptionstr | NoneOptional description
cycle_typestr"product" or "access"
statusstr"open", "in_review", "completed", "cancelled"
due_datedatetime | NoneReview deadline
start_datedatetime | NoneWhen the cycle was created
completed_atdatetime | NoneWhen the cycle was completed
space_idUUID | NoneSpace the cycle belongs to
created_by_idUUID | NoneUser who created the cycle
audit_countintTotal audit items
reviewed_countintDecided audit items
auditslist[RecertificationAudit]Embedded audits (when fetched via get_cycle)

RecertificationAudit

FieldTypeDescription
idUUIDAudit identifier
cycle_idUUIDParent cycle
resource_idUUIDResource being reviewed
resource_namestr | NoneResource display name
resource_typestr | NoneResource type (e.g., Table, Dashboard, SourceSystemRole)
statusstr"pending", "approved", "rejected", "expired"
reviewer_idUUID | NoneWho made the decision
reviewed_atdatetime | NoneWhen the decision was made
commentsstr | NoneReviewer comments
product_idstr | NoneAssociated data product ID (product cycles)
source_system_idstr | NoneAssociated source system ID (access cycles)
has_pending_requestboolWhether a recertification request is in-flight
request_idstr | NoneID of the linked recertification request

PopulateResult

FieldTypeDescription
createdintNumber of audit items created

RecertifyAllResult

FieldTypeDescription
createdintNumber of recertification requests created

FilterSuggestions

FieldTypeDescription
tagslist[str]Distinct tag values in the space
product_typeslist[str]Distinct product type values
criticalitieslist[str]Distinct criticality values

Example: Full Cycle Automation

from qarion import QarionClient

async def run_quarterly_review():
async with QarionClient(api_key="your-api-key") as client:

# 1. Create a cycle with filters
cycle = await client.recertification.create_cycle(
"marketing-analytics",
name="Q1 2026 Review",
due_date="2026-03-31T23:59:59Z",
cycle_type="product",
)

# 2. Scope to PII products only
await client.recertification.update_config(
"marketing-analytics",
cycle.id,
filters={"tags": ["pii"]},
request_title_template="Recertify {{ product_name }}",
)

# 3. Populate audit items
result = await client.recertification.populate_cycle(
"marketing-analytics", cycle.id
)
print(f"Populated {result.created} items")

# 4. Create requests for all pending items
bulk = await client.recertification.recertify_all(
"marketing-analytics", cycle.id
)
print(f"Created {bulk.created} requests")

# 5. (Alternatively) Review each audit item directly
detail = await client.recertification.get_cycle(
"marketing-analytics", cycle.id
)
for audit in detail.audits:
if audit.status == "pending":
await client.recertification.review_audit(
audit.id,
status="approved",
comments="Auto-approved via quarterly script.",
)

# 6. Complete the cycle
await client.recertification.complete_cycle(
"marketing-analytics", cycle.id
)
print("Cycle completed.")