Cikit Data
Overview
cikit data stores structured information associated with CI pipelines and logical runs.
Typical values include:
test counts and failures
coverage metrics
lint statistics
build duration
warning and error counts
memory usage
other scalar or structured run metrics
cikit data supports local persistence, optional remote synchronization, and historical timeline queries.
It is separate from the artifact system. cikit data stores structured values; the artifact registry stores metadata for generated files and directories.
Architecture
The data stack consists of three main layers:
CiRunEnvironment
|
+-- RunContext
|
+-- CikitData
|
+-- local JSON cache
|
+-- optional CikitDataClient
|
+-- remote cikit Data API
CikitData provides the high-level local and remote data operations.
RunContext binds a CikitData instance to one logical run and one
pipeline id.
CiRunEnvironment uses that run context and exposes the most common
operations through the active CI environment.
Access Modes
CikitData supports three access modes.
Cache-only Mode
Only a local cache directory is configured:
from pathlib import Path
from cikit.data import build_cikit_data
data = build_cikit_data(
project="my_project",
cache_dir=Path("public/cikit_data"),
)
Run updates are written locally. Operations requiring historical server data, such as timeline queries, are unavailable.
Remote-only Mode
Only a remote API is configured:
from cikit.data import build_cikit_data
data = build_cikit_data(
project="my_project",
base_url="https://example.com/api",
token="secret",
)
Run updates are sent to the remote service without creating local run cache files.
Hybrid Mode
A local cache and remote API are both configured:
from pathlib import Path
from cikit.data import build_cikit_data
data = build_cikit_data(
project="my_project",
cache_dir=Path("public/cikit_data"),
base_url="https://example.com/api",
token="secret",
)
Updates are written to the local cache first and then synchronized with the remote API.
The standard cikit environment always configures CIKIT_DATA_DIR and
therefore provides local cache access. Remote access is enabled additionally
when CIKIT_DATA_BASE_URL is configured.
Environment Configuration
The cikit environment provides the following settings used by the data layer:
Variable |
Purpose |
|---|---|
|
Logical project name used for cikit data addressing. |
|
Local directory for cached run data and related local metadata. |
|
Optional base URL of the remote cikit Data API. |
|
Optional authentication token for the remote API. |
By default:
CIKIT_DATA_DIR=${PUBLIC_DIR}/cikit_data
CIKIT_DATA_BASE_URL and CIKIT_DATA_API_TOKEN are optional.
Project Addressing
Every remote request is associated with one project key. The key is derived
from the logical project name and the optional tool.cikit.data_scope value
from pyproject.toml.
Without a configured scope, the effective key is simply:
PROJECT_NAME
For example:
PROJECT_NAME=cikit
-> cikit
A scope can be configured as project metadata:
[project]
name = "cikit"
[tool.cikit]
data_scope = "svesch"
The resulting remote project key is then:
svesch/cikit
The same key is used during local execution and in every CI provider. Provider metadata does not participate in cikit data addressing.
Logical Runs
Data inside a project is grouped by logical run name.
Typical run names are:
build
unittests
systemtests
coverage
ruff
pylint
docs
The run name identifies one independent set of values.
For example:
build:
build_time
warnings
errors
coverage:
coverage
line_rate
pylint:
score
violations
The same run name is used for both local cache data and remote run data.
RunContext
RunContext binds three values together:
a configured
CikitDatainstancea pipeline id
a logical run name
Conceptually:
CikitData
+
pipeline_id
+
run_name
|
v
RunContext
This removes the need to repeatedly pass the run name and pipeline id to every data operation.
Example:
from cikit.data import RunContext
context = RunContext(
cikit_data,
pipeline_id="12345",
run_name="build",
)
context.set("build_time", 4.2)
context.update({
"warnings": 0,
"errors": 0,
})
CiRunEnvironment Integration
CiRunEnvironment creates a RunContext automatically for its logical
run.
The run context is available as:
env.run
The logical run name is exposed as:
env.name
Common operations are wrapped directly by the environment:
env.data_set("build_time", 4.2)
env.data_update({
"warnings": 0,
"errors": 0,
})
data = env.data
timeline = env.timeline(
["build_time", "warnings"],
limit=20,
)
This is the normal API used by cikit macros and project CI commands.
Updating Run Data
A single value can be stored through the run environment:
env.data_set("coverage", 92.5)
Multiple values can be merged in one operation:
env.data_update({
"tests": 120,
"failures": 0,
"errors": 0,
})
The behavior depends on the configured access mode.
Local Cache
When a local cache is configured, new values are merged into the existing JSON data for that run.
Existing keys not included in the update remain unchanged.
Remote Backend
When a remote client is configured, only the values supplied by the current update are sent to the server.
A remote update requires a pipeline id.
Hybrid Updates
In hybrid mode, the local cache is updated before the remote request is made.
This means the local update may already have been persisted if the subsequent remote synchronization fails.
Local Cache Format
Local run data is stored as one JSON file per logical run below
CIKIT_DATA_DIR.
Example:
public/
`-- cikit_data/
|-- build.json
|-- coverage.json
|-- pylint.json
`-- unittests.json
A run file contains the merged values of that run.
Example build.json:
{
"build_time": 4.2,
"warnings": 0,
"errors": 0
}
Repeated updates merge new values into the existing file.
Reading Current Run Data
The current run’s locally cached data is exposed by CiRunEnvironment:
data = env.data
Internally this uses RunContext.get_data().
get_data():
reads only the local cache
does not query the remote API
returns a shallow dictionary copy
returns an empty dictionary when the run file does not exist
requires a configured local cache directory
Reading a Latest Value
CikitData.latest() and RunContext.latest() resolve one value using a
local-first strategy.
Example:
value = env.run.latest("build_time")
Resolution order:
Read the local run cache when configured.
Return the cached value when the requested key exists.
Otherwise query the remote API when configured.
Raise an error if neither source can provide the value.
Only the resolved value is returned, not the complete remote response.
Timeline Queries
Timeline queries provide historical values across multiple pipeline entries.
Unlike latest(), a timeline query always uses the remote API. The local
cache contains only the current locally stored run state and is not used as a
historical data source.
Through CiRunEnvironment:
from cikit.data import RefKey
timeline = env.timeline(
["build_time", "warnings"],
ref_key=RefKey.INDEX_DESC,
limit=20,
)
The result has a normalized structure:
{
"refs": [-2, -1, 0],
"series": {
"build_time": [4.8, 4.5, 4.2],
"warnings": [1, 2, 0],
},
}
Each series contains one value for every reference. Timeline entries are
returned from oldest to newest. With RefKey.INDEX_DESC, the newest entry is
0, the previous entry is -1, and so on.
Missing values are represented as None after decoding the remote JSON
null value.
Remote key prefixes are removed before the high-level result is returned, so
the keys in series match the run-local keys requested by the caller.
Timeline queries require remote access. Without a configured remote client, they raise a recoverable cikit error.
Reference Keys
RefKey selects which pipeline property is used as the timeline reference.
Available values are:
Reference |
Value |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
The low-level CikitData and RunContext timeline APIs default to
RefKey.TIMESTAMP.
CiRunEnvironment.timeline() defaults to RefKey.INDEX_DESC, which is
well suited to compact reports and charts where the newest entry is represented
relative to previous entries.
Timeline chart generation is described in Timeline Charts.
Remote Key Format
The remote API stores run values below the runs namespace.
The high-level API converts a run and local key into:
runs.<run>.<key>
Examples:
runs.build.build_time
runs.coverage.coverage
runs.pylint.score
Callers using CikitData or RunContext normally work with the shorter
run-local key:
env.run.latest("build_time")
The fully qualified key is an implementation detail of communication with the remote API.
Pipeline Entries
The remote backend groups run updates below pipeline entries.
A pipeline entry contains provider and revision context and is created through:
cikit_data.create(
pipeline_id="12345",
ci_provider="GITLAB",
commit_hash="abcdef123456",
)
In cache-only mode, create() performs no remote operation and returns an
empty dictionary.
Project CI initialization uses the active environment to provide the pipeline id, provider, and commit hash to this operation.
Low-Level Remote Client
CikitDataClient implements the HTTP communication used by CikitData.
The high-level API should normally be preferred, but the client defines the remote behavior.
It uses:
a shared
requests.Sessionretries for temporary server-side failures
three retry attempts
retry status codes
500,502,503, and504a connection timeout of 5 seconds
a read timeout of 30 seconds
The client exposes operations for:
pipeline creation
run updates
latest-value queries
timeline queries
Authentication is sent through the X-Auth-Token header when a token is
configured.
Cikit Data and Artifacts
cikit data and artifacts are independent mechanisms.
cikit data stores structured values:
build_time = 4.2
warnings = 0
coverage = 92.5
The artifact registry stores metadata for persistent files and directories:
firmware.bin -> BUILD
build.log -> LOG
chart_build.svg -> TIMELINE
Both mechanisms are associated with logical runs, but they serve different
purposes. Cached run data and artifact registry metadata are stored below
CIKIT_DATA_DIR. The artifact files and directories themselves are stored
below PUBLIC_DIR.
In particular:
cikit data does not store artifact metadata as run values
timeline data is historical cikit data, not a list of
TIMELINEartifactsTIMELINEartifacts are rendered SVG files registered through the artifact mechanismreports may combine structured cikit data with registered artifacts
For artifact storage and lookup semantics, see Artifacts.
Error Behavior
Configuration and invalid data operations generally raise CiToolsError.
Remote synchronization failures are reported through cikit synchronization errors derived from the common cikit error handling.
Some unavailable operations are intentionally recoverable. For example:
timeline access without a remote client
reading cached run data without a configured cache directory
A hybrid update writes the local cache before contacting the remote API. Therefore a remote failure does not imply that the local update was rolled back.