Fixes to documentation to fix AI voice and to move some development details to issues. authored by Rob Oakes's avatar Rob Oakes
# Sonador Design Patterns # Sonador Design Patterns
The Sonador client libraries are designed around a single idea: **interacting with a remote medical The Sonador client libraries are designed so that interacting with a remote medical imaging system
imaging system should feel like working with ordinary Python objects.** Rather than assembling URLs feels like working with ordinary Python objects. Rather than assembling URLs and parsing JSON by
and parsing JSON by hand, a developer connects to a server, asks it for a resource, and receives a hand, a developer connects to a server, asks it for a resource, and receives a model whose properties
model whose properties and methods map onto the underlying DICOM/Sonador data and the operations the and methods map onto the underlying DICOM/Sonador data and the operations the server supports. Every
server supports. The libraries favor *predictability over cleverness* — every resource follows the resource follows the same conventions, so once you have learned how to work with one (e.g. a study)
same conventions, so once you have learned how to work with one (e.g. a study) you already know how you already know how to work with the rest (series, instances, reports, segmentations).
to work with the rest (series, instances, reports, segmentations).
These patterns build directly on the These patterns build directly on the
[Guru Client](https://code.oak-tree.tech/django-apps/guru/-/wikis/dev.client-tools) (servers, [Guru Client](https://code.oak-tree.tech/django-apps/guru/-/wikis/dev.client-tools) (servers,
...@@ -13,11 +12,11 @@ models, collections, and the `fetch_*` helpers). This page describes how Sonador ...@@ -13,11 +12,11 @@ models, collections, and the `fetch_*` helpers). This page describes how Sonador
"rules of thumb" that govern the Sonador IO client specifically. "rules of thumb" that govern the Sonador IO client specifically.
* Sonador client libraries provide an object relational map (ORM) interface to interact with system resources stored within Sonador and Orthanc. * Sonador client libraries provide an object relational map (ORM) interface to interact with system resources stored within Sonador and Orthanc.
- The [Sonador IO Client](https://code.oak-tree.tech/oak-tree/medical-imaging/sonador-client) libary (which is a core dependency of all other Sonador libraries) inherits from the [Guru Client](https://code.oak-tree.tech/guru-labs/guru-client), which provides base utilities and core object clases. - The [Sonador IO Client](https://code.oak-tree.tech/oak-tree/medical-imaging/sonador-client) library (which is a core dependency of all other Sonador libraries) inherits from the [Guru Client](https://code.oak-tree.tech/guru-labs/guru-client), which provides base utilities and core object classes.
- The three core classes are **servers** (which represent the data source), **model** (which defines a resource, its fundamental properties, and API methods), and **collections** (which allow for interaction with logical sets of models). - The three core classes are **servers** (which represent the data source), **model** (which defines a resource, its fundamental properties, and API methods), and **collections** (which allow for interaction with logical sets of models).
* Sonador API methods follow traditional REST-like principals. * Sonador API methods follow traditional REST-like principles.
+ Operations on the remote server utilize HTTP verbs to describe an action. + Operations on the remote server utilize HTTP verbs to describe an action.
+ Data payloads are sent as JSON (representated as `dict` instances within the library) + Data payloads are sent as JSON (represented as `dict` instances within the library)
* Sonador model classes define properties and interfaces to create, retrieve, update, and delete model instances. _The four methods are often called `CRUD` operations._ * Sonador model classes define properties and interfaces to create, retrieve, update, and delete model instances. _The four methods are often called `CRUD` operations._
...@@ -88,7 +87,7 @@ an in-memory hashmap of models keyed by `pk` for rapid `get_modelinstance(pk)` l ...@@ -88,7 +87,7 @@ an in-memory hashmap of models keyed by `pk` for rapid `get_modelinstance(pk)` l
* By convention, every Guru, Oak-Tree, and Sonador API resource is associated with **two primary endpoints**. * By convention, every Guru, Oak-Tree, and Sonador API resource is associated with **two primary endpoints**.
- **A "management" endpoint** that is used for describing the resource, retrieving collections of logically grouped models, and creating new instances of the model. - **A "management" endpoint** that is used for describing the resource, retrieving collections of logically grouped models, and creating new instances of the model.
creating new models that are part of the collection. creating new models that are part of the collection.
+ `OPTIONS`: retrieve schema and access details for the model type (the response will also include access paramters and query/filter options) + `OPTIONS`: retrieve schema and access details for the model type (the response will also include access parameters and query/filter options)
+ `GET`: retrieve a collection of models. _The endpoint will often have search capabilities that can be accessed via query parameters and pagination information available from headers._ + `GET`: retrieve a collection of models. _The endpoint will often have search capabilities that can be accessed via query parameters and pagination information available from headers._
+ `POST`: create a new model instance in the collection. + `POST`: create a new model instance in the collection.
- **A "details" endpoint** (also sometimes called a REST endpoint) that is associated with a specific instance of the model and used to retrieve details of the instance, make updates, or to remove it from the server. - **A "details" endpoint** (also sometimes called a REST endpoint) that is associated with a specific instance of the model and used to retrieve details of the instance, make updates, or to remove it from the server.
...@@ -146,11 +145,11 @@ interface as remote resources but hold data the application has assembled itself ...@@ -146,11 +145,11 @@ interface as remote resources but hold data the application has assembled itself
model before (or without) a round-trip to a server — bulk-prepping files for upload, or caching model before (or without) a round-trip to a server — bulk-prepping files for upload, or caching
results client-side. results client-side.
> 📘 The data-preparation tasks in `sonador.tasks` (uploads, reindexing) build on these helpers. > The data-preparation tasks in `sonador.tasks` (uploads, reindexing) build on these helpers.
### `remote` ### `remote`
The `remote` axis is the heart of day-to-day use: models and collections backed by the Sonador and The `remote` axis covers most day-to-day use: models and collections backed by the Sonador and
Orthanc server APIs. A model (sometimes called a *data object*) maps a server resource to a Python Orthanc server APIs. A model (sometimes called a *data object*) maps a server resource to a Python
object whose properties expose its DICOM tags and whose methods expose the operations the server object whose properties expose its DICOM tags and whose methods expose the operations the server
supports. supports.
...@@ -199,7 +198,7 @@ the standard collection/model conventions but are *parented* to a resource: they ...@@ -199,7 +198,7 @@ the standard collection/model conventions but are *parented* to a resource: they
`parent.pacs` and build their URLs from the parent's `comments_url` (with a DICOMweb variant). This is `parent.pacs` and build their URLs from the parent's `comments_url` (with a DICOMweb variant). This is
the general pattern for any DICOM-extension data Sonador layers on top of Orthanc resources. the general pattern for any DICOM-extension data Sonador layers on top of Orthanc resources.
> 📘 Extension models require a valid parent; their `create`/`fetch`/`fetch_modelinstance` > Extension models require a valid parent; their `create`/`fetch`/`fetch_modelinstance`
> class methods take the parent resource (not the server) as their first argument. > class methods take the parent resource (not the server) as their first argument.
...@@ -222,7 +221,7 @@ which is the basis for displaying measurements and findings against the images t ...@@ -222,7 +221,7 @@ which is the basis for displaying measurements and findings against the images t
The same structured-instance base classes are shared with DICOM-SEG (segmentation) documents, so The same structured-instance base classes are shared with DICOM-SEG (segmentation) documents, so
segmentations resolve their referenced series the same way. segmentations resolve their referenced series the same way.
> 📘 `sr` relates to `local` and `remote` as follows: `remote` provides the transport and the resource > `sr` relates to `local` and `remote` as follows: `remote` provides the transport and the resource
> hierarchy, `sr` adds the structured-content parsing on top of it, and `local` (with the > hierarchy, `sr` adds the structured-content parsing on top of it, and `local` (with the
> `sonador.helpers.sr` utilities) handles SR data that is being read from or written to disk rather > `sonador.helpers.sr` utilities) handles SR data that is being read from or written to disk rather
> than fetched from a server. > than fetched from a server.