---
question: How do I publish a LogProcess event?
kind: task
via_web: na
via_cli: na
via_python: available
via_api: na
via_config: na
ref_python: events.publish
prereq: An in-engine module that lists `EventService` in its dependencies, and the event service in `config.yaml` (`sqlite` by default). See [Events](/user-guide/build/platform/events-overview).
next:
  - /capabilities/build/platform/stream-events
  - /capabilities/build/platform/events-overview
---

# Record an event

An event is an instance of a class that inherits `LogProcess`. Publishing it appends it to the log, then broadcasts it to live subscribers. If the broadcast fails, the log row still stands.

## Web UI

Not applicable. The event log is append-only and Nexus only reads it: **Events** in the sidebar and **System** › **Data** › **Events**, for super admins. Use the Python steps on this page.

## CLI

Not applicable. There is no `abi` command that publishes an event. Use the Python steps on this page. The command list is the [CLI reference](/user-guide/reference/cli).

## Python

### Declare the service

```python title="src/my_module/__init__.py"
from naas_abi_core.module.Module import BaseModule, ModuleDependencies
from naas_abi_core.services.event.EventService import EventService


class ABIModule(BaseModule):
    dependencies: ModuleDependencies = ModuleDependencies(
        modules=[],
        services=[EventService],
    )
```

### Declare the event type

Write the class in an ontology file. It imports the event ontology by its IRI and subclasses `abi:LogProcess`:

```turtle title="src/my_module/ontologies/modules/OrderEvents.ttl"
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix abi: <http://ontology.naas.ai/abi/> .
@prefix orders: <http://ontology.naas.ai/abi/orders/> .

orders:OrderEvents a owl:Ontology ;
    owl:imports <http://ontology.naas.ai/abi/EventService> ;
    abi:pythonPackage "my_module" ;
    abi:ontologyResource "ontologies/modules/OrderEvents.ttl" ;
    abi:pythonResource "ontologies/modules/OrderEvents.py" .

orders:OrderShipped a owl:Class ;
    rdfs:label "OrderShipped"@en ;
    rdfs:subClassOf abi:LogProcess .

orders:orderId a owl:DatatypeProperty ;
    rdfs:label "order_id"@en ;
    rdfs:domain orders:OrderShipped ;
    rdfs:range xsd:string .
```

### Generate the class

```bash
uv run python -m naas_abi_core.utils.onto2py src/my_module/ontologies/modules/OrderEvents.ttl
```

It writes `OrderEvents.py` next to the file. Do not edit it: change the ontology and generate again. Without the `owl:imports` line, the generated class gets its own copy of `LogProcess` and `publish` rejects it.

### Publish

```python
from my_module.ontologies.modules.OrderEvents import OrderShipped

stored = self.engine.services.events.publish(OrderShipped(order_id="A-1042"))
```

`stored` is a `StoredEvent`: `seq`, `event_type`, `timestamp` and the JSON `payload`. `publish` fills `created_at` when it is empty, and `actor_user_id`, `actor_workspace_id` and `triggered_via` from the current request. It raises `InvalidEventError` when the object is not a `LogProcess`.

### Read it back

```python
recent = self.engine.services.events.query(OrderShipped, newest_first=True, limit=10)
```

Live listeners are [Stream events](/user-guide/build/platform/stream-events).

## REST API

Not applicable. The event log is append-only: the System routes of the Nexus API read it, and a write answers 405. Use the Python steps on this page.

## Config

Not applicable. An event is a call. `services.event` only picks where the log lives: see [Events](/user-guide/build/platform/events-overview#backends).
