Write DataSignals data#

Use patch_data() to update selected metric keys and put_data() to insert or replace complete rows. Both methods are available on the synchronous API and asynchronous AsyncAPI facades.

Warning

put_data(..., on_conflict="replace") replaces the complete metrics document for an existing timestamp, site, and location. Metric keys omitted from the request are removed. Prefer patch_data() for ordinary partial updates.

Conflict behavior#

Method

on_conflict

Existing row behavior

PUT

replace

Replace the complete metrics document

PUT

nothing

Leave the existing row unchanged

PATCH

replace

Merge keys, with incoming values winning

PATCH

nothing

Add only keys that do not exist

Both methods insert the row when its timestamp, site, and location combination does not exist.

Write one or more rows#

Each row must contain timestamp, site, location, and at least one metric:

from api_24sea.datasignals.core import API

api = API()
api.authenticate("username", "password")

result = api.patch_data(
    [
        {
            "timestamp": "2026-07-23T10:00:00Z",
            "site": "windfarm",
            "location": "WFA01",
            "mean_WFA01_windspeed": 10.5,
        },
        {
            "timestamp": "2026-07-23T10:00:00Z",
            "site": "windfarm",
            "location": "WFA02",
            "mean_WFA02_windspeed": 10.8,
        },
    ],
    on_conflict="replace",
)

The result includes processed_rows, affected_rows, skipped_rows, and projects.

Write a DataFrame#

site and location can be supplied once when they are not columns:

result = api.patch_data(
    frame,
    site="windfarm",
    location="WFA01",
)

A timestamp column or an index named timestamp is required. Sparse PATCH frames omit pandas missing values. PUT rejects missing metric values to avoid silently replacing a complete metrics document with a sparse row. Use a mapping with an explicit None value to write JSON null.

The synchronous pandas accessor provides the same convenience:

result = frame.datasignals.patch_data(
    site="windfarm",
    location="WFA01",
)

Write asynchronously#

from api_24sea.datasignals.core import AsyncAPI

api = AsyncAPI()
api.authenticate("username", "password")

result = await api.patch_data(
    payload,
    on_conflict="replace",
)

The async facade uses the same validation and response contract. Write retries are disabled by default; set max_retries explicitly when retrying an HTTP 502 is appropriate.

Permissions#

Writes require a staff or superuser account with a DataSignals write permission covering the requested project, location, timestamp, and every metric.

For local Sample testing, configure the client before authentication:

api = API()
api.base_url = "https://api.24sea.localhost/routes/v1"
api.authenticate("admin", "password")

Use generated test timestamps and ensure exact cleanup of every written row. Do not use Sample write examples against production.