oboa 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oboa-0.1.0/AUTHORS +5 -0
- oboa-0.1.0/LICENSE +19 -0
- oboa-0.1.0/MANIFEST.in +6 -0
- oboa-0.1.0/PKG-INFO +454 -0
- oboa-0.1.0/README.md +424 -0
- oboa-0.1.0/pyproject.toml +56 -0
- oboa-0.1.0/setup.cfg +4 -0
- oboa-0.1.0/src/oboa/__init__.py +0 -0
- oboa-0.1.0/src/oboa/config/__init__.py +3 -0
- oboa-0.1.0/src/oboa/config/datamodel.json +11 -0
- oboa-0.1.0/src/oboa/config/engine.json +19 -0
- oboa-0.1.0/src/oboa/config/orchestrator_configuration.xml +3 -0
- oboa-0.1.0/src/oboa/datamodel/__init__.py +3 -0
- oboa-0.1.0/src/oboa/datamodel/base.py +22 -0
- oboa-0.1.0/src/oboa/datamodel/errors.py +15 -0
- oboa-0.1.0/src/oboa/datamodel/functions.py +55 -0
- oboa-0.1.0/src/oboa/datamodel/oboa_data_model.dbm +265 -0
- oboa-0.1.0/src/oboa/datamodel/oboa_data_model.sql +229 -0
- oboa-0.1.0/src/oboa/datamodel/orchestrated_files.py +223 -0
- oboa-0.1.0/src/oboa/engine/__init__.py +3 -0
- oboa-0.1.0/src/oboa/engine/archive_client.py +69 -0
- oboa-0.1.0/src/oboa/engine/commands.py +377 -0
- oboa-0.1.0/src/oboa/engine/daemon.py +240 -0
- oboa-0.1.0/src/oboa/engine/engine.py +1117 -0
- oboa-0.1.0/src/oboa/engine/errors.py +75 -0
- oboa-0.1.0/src/oboa/engine/functions.py +345 -0
- oboa-0.1.0/src/oboa/engine/operators.py +23 -0
- oboa-0.1.0/src/oboa/engine/parsing.py +194 -0
- oboa-0.1.0/src/oboa/engine/query.py +431 -0
- oboa-0.1.0/src/oboa/engine/xpath_functions.py +43 -0
- oboa-0.1.0/src/oboa/logging.py +139 -0
- oboa-0.1.0/src/oboa/processors/__init__.py +3 -0
- oboa-0.1.0/src/oboa/processors/base_processor.py +251 -0
- oboa-0.1.0/src/oboa/schemas/__init__.py +3 -0
- oboa-0.1.0/src/oboa/schemas/oboa_orchestrator_configuration.xsd +25 -0
- oboa-0.1.0/src/oboa/scripts/__init__.py +3 -0
- oboa-0.1.0/src/oboa/scripts/initialize_oboa_ddbb.sh +25 -0
- oboa-0.1.0/src/oboa/scripts/oboa_configure.py +22 -0
- oboa-0.1.0/src/oboa/scripts/oboa_daemon.py +22 -0
- oboa-0.1.0/src/oboa/scripts/oboa_init.py +145 -0
- oboa-0.1.0/src/oboa/scripts/oboa_init_ddbb.sh +99 -0
- oboa-0.1.0/src/oboa/scripts/oboa_orchestrate.py +22 -0
- oboa-0.1.0/src/oboa/scripts/oboa_poll.py +22 -0
- oboa-0.1.0/src/oboa/scripts/oboa_query.py +22 -0
- oboa-0.1.0/src/oboa/scripts/start_oboa.sh +6 -0
- oboa-0.1.0/src/oboa.egg-info/PKG-INFO +454 -0
- oboa-0.1.0/src/oboa.egg-info/SOURCES.txt +49 -0
- oboa-0.1.0/src/oboa.egg-info/dependency_links.txt +1 -0
- oboa-0.1.0/src/oboa.egg-info/entry_points.txt +7 -0
- oboa-0.1.0/src/oboa.egg-info/requires.txt +9 -0
- oboa-0.1.0/src/oboa.egg-info/top_level.txt +1 -0
oboa-0.1.0/AUTHORS
ADDED
oboa-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright 2026-2026 BOA authors and contributors <see AUTHORS file>.
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
5
|
+
the Software without restriction, including without limitation the rights to
|
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
8
|
+
so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
oboa-0.1.0/MANIFEST.in
ADDED
oboa-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: oboa
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Orchestrator for Business Operations Analysis
|
|
5
|
+
Author: Daniel Brosnan Blázquez
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Daniel-Brosnan-Blazquez/oboa
|
|
8
|
+
Project-URL: Repository, https://github.com/Daniel-Brosnan-Blazquez/oboa
|
|
9
|
+
Project-URL: Issues, https://github.com/Daniel-Brosnan-Blazquez/oboa/issues
|
|
10
|
+
Keywords: orchestration,archiving,file-processing,postgresql
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Topic :: System :: Archiving
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
License-File: AUTHORS
|
|
21
|
+
Requires-Dist: aboa==0.2.0
|
|
22
|
+
Requires-Dist: sqlalchemy==1.3.22
|
|
23
|
+
Requires-Dist: psycopg2-binary==2.9.11
|
|
24
|
+
Requires-Dist: python-dateutil==2.9.0.post0
|
|
25
|
+
Requires-Dist: lxml==6.0.2
|
|
26
|
+
Provides-Extra: tests
|
|
27
|
+
Requires-Dist: pytest==8.4.2; extra == "tests"
|
|
28
|
+
Requires-Dist: pytest-cov==7.0.0; extra == "tests"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# OBOA
|
|
32
|
+
|
|
33
|
+
Orchestrator for Business Operations Analysis.
|
|
34
|
+
|
|
35
|
+
OBOA polls an input directory, matches ready files against XML orchestration
|
|
36
|
+
rules, delegates archival storage to ABOA, optionally stages files for executable
|
|
37
|
+
data processors, and keeps a PostgreSQL inventory of configuration history,
|
|
38
|
+
orchestrated files, and failed operations. The current implementation exposes
|
|
39
|
+
command line tools and Python interfaces through `oboa.engine.engine.Engine` and
|
|
40
|
+
`oboa.engine.query.Query`.
|
|
41
|
+
|
|
42
|
+
## Contents
|
|
43
|
+
|
|
44
|
+
- [What OBOA Provides](#what-oboa-provides)
|
|
45
|
+
- [Quick Start With Docker](#quick-start-with-docker)
|
|
46
|
+
- [Install From PyPI](#install-from-pypi)
|
|
47
|
+
- [Local Python Setup](#local-python-setup)
|
|
48
|
+
- [Runtime Configuration](#runtime-configuration)
|
|
49
|
+
- [Orchestration Configuration XML](#orchestration-configuration-xml)
|
|
50
|
+
- [Command Line Tools](#command-line-tools)
|
|
51
|
+
- [Python API](#python-api)
|
|
52
|
+
- [Operation Flow Schematics](#operation-flow-schematics)
|
|
53
|
+
- [Data Model](#data-model)
|
|
54
|
+
- [Development Layout](#development-layout)
|
|
55
|
+
- [Tests](#tests)
|
|
56
|
+
- [Publishing To PyPI](#publishing-to-pypi)
|
|
57
|
+
|
|
58
|
+
## What OBOA Provides
|
|
59
|
+
|
|
60
|
+
- Poll an input directory once, continuously, or through a managed daemon.
|
|
61
|
+
- Validate and activate XML orchestration configurations.
|
|
62
|
+
- Match files by mask using lxml XPath evaluation and OBOA XPath helper
|
|
63
|
+
functions.
|
|
64
|
+
- Sort ready files by configured orchestration priority before processing each
|
|
65
|
+
polling pass.
|
|
66
|
+
- Delegate archival storage to ABOA and pass the matched OBOA file group as
|
|
67
|
+
archive metadata.
|
|
68
|
+
- Optionally delete input files after successful archive delegation.
|
|
69
|
+
- Stage processor-backed files into a configurable internal processing folder by
|
|
70
|
+
hard-linking when possible and copying when hard-linking is not available.
|
|
71
|
+
- Execute configured data processors with OBOA environment variables describing
|
|
72
|
+
the orchestrated file, staged path, group, and configuration UUID.
|
|
73
|
+
- Move failed archived or staged inputs out of the entry point into
|
|
74
|
+
`<error_dir>/<YEAR>/<MONTH>/<DAY>/<file_name>`, so failed inputs are not
|
|
75
|
+
orchestrated repeatedly.
|
|
76
|
+
- Keep PostgreSQL inventory rows for active and historical orchestration
|
|
77
|
+
configurations and orchestrated files.
|
|
78
|
+
- Record failed operations in `orchestration_operations` while successful
|
|
79
|
+
operations are written only to the log.
|
|
80
|
+
|
|
81
|
+
## Quick Start With Docker
|
|
82
|
+
|
|
83
|
+
The development compose file starts an OBOA container and a PostgreSQL/PostGIS
|
|
84
|
+
database container. The source checkout is mounted into the OBOA container at
|
|
85
|
+
`/oboa`, and the container user can be mapped to the host user with
|
|
86
|
+
`UID_HOST_USER` and `GID_HOST_USER`.
|
|
87
|
+
|
|
88
|
+
The development image copies the source and installs OBOA in editable mode into
|
|
89
|
+
`/usr/local/oboa-venv` during its build, including the runtime and test
|
|
90
|
+
dependencies declared in `pyproject.toml`. At runtime, the mounted checkout replaces
|
|
91
|
+
the copied source, so source edits take effect immediately. Rebuild the image
|
|
92
|
+
when dependencies change.
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
UID_HOST_USER=$(id -u) GID_HOST_USER=$(id -g) docker compose -f compose_dev.yml up -d --build
|
|
96
|
+
docker compose -f compose_dev.yml exec oboa initialize_oboa_ddbb.sh
|
|
97
|
+
docker compose -f compose_dev.yml exec oboa oboa_configure.py --configuration /oboa/src/tests/inputs/orchestrator_texts_without_processor.xml
|
|
98
|
+
docker compose -f compose_dev.yml exec oboa oboa_query.py --configurations --active true
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`initialize_oboa_ddbb.sh` calls `oboa_init.py -y` and recreates the configured
|
|
102
|
+
database from `src/oboa/datamodel/oboa_data_model.sql`, so it deletes existing
|
|
103
|
+
OBOA inventory data for that database.
|
|
104
|
+
|
|
105
|
+
OBOA archives through ABOA by default. Both Docker images install
|
|
106
|
+
`aboa==0.2.0` from PyPI during their builds.
|
|
107
|
+
Both Compose files set these ABOA variables:
|
|
108
|
+
|
|
109
|
+
- `ABOA_DDBB_HOST`: defaults to `oboa_db`; override it in the host environment
|
|
110
|
+
to use another PostgreSQL server.
|
|
111
|
+
- `ABOA_LOG_PATH`: `/log`, shared with OBOA logs.
|
|
112
|
+
- `ABOA_DEFAULT_ARCHIVE_PATH`: `/aboa_archive`, used as the fallback when
|
|
113
|
+
the XML archive configuration cannot be activated. The XML `root_directory`
|
|
114
|
+
takes precedence.
|
|
115
|
+
|
|
116
|
+
ABOA uses its bundled configuration, including the `aboadb` database and `aboa`
|
|
117
|
+
database user. Initialize its database before archiving:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
docker compose -f compose_dev.yml exec oboa aboa_init.py
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
For custom configuration, mount a directory containing ABOA's `datamodel.json`,
|
|
124
|
+
`engine.json`, and `archive_configurations.xml`, then set `ABOA_RESOURCES_PATH`
|
|
125
|
+
to that container directory.
|
|
126
|
+
|
|
127
|
+
## Install From PyPI
|
|
128
|
+
|
|
129
|
+
OBOA requires Python 3.9 or newer and Linux with Bash. Install it in a virtual
|
|
130
|
+
environment:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
python3 -m venv .venv
|
|
134
|
+
source .venv/bin/activate
|
|
135
|
+
python -m pip install oboa
|
|
136
|
+
oboa_poll.py --help
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The package includes its default configuration, XML schema, SQL data model, and
|
|
140
|
+
shell helpers. PostgreSQL client tools (`psql`) must be installed separately to
|
|
141
|
+
initialize a database with `oboa_init.py`; a reachable PostgreSQL server is
|
|
142
|
+
required for orchestration. Set `OBOA_DDBB_HOST` and `ABOA_DDBB_HOST` as needed,
|
|
143
|
+
and follow the runtime configuration instructions below before processing files.
|
|
144
|
+
|
|
145
|
+
## Local Python Setup
|
|
146
|
+
|
|
147
|
+
For local development outside Docker, install from the repository root:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
python3 -m venv .venv
|
|
151
|
+
source .venv/bin/activate
|
|
152
|
+
python -m pip install -e ".[tests]"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Installing OBOA automatically installs `aboa==0.2.0` from PyPI as a required
|
|
156
|
+
runtime dependency and the default archive manager.
|
|
157
|
+
|
|
158
|
+
Set the runtime paths before importing or running OBOA:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
export OBOA_RESOURCES_PATH="$PWD/src/oboa/config"
|
|
162
|
+
export OBOA_SCHEMAS_PATH="$PWD/src/oboa/schemas"
|
|
163
|
+
export OBOA_LOG_PATH="$PWD/log"
|
|
164
|
+
export OBOA_POLLING_DIR="/tmp/oboa_polling"
|
|
165
|
+
export OBOA_PROCESSING_DIR="/tmp/oboa_processing"
|
|
166
|
+
export OBOA_ERROR_DIR="/tmp/oboa_error"
|
|
167
|
+
mkdir -p "$OBOA_LOG_PATH" "$OBOA_POLLING_DIR" "$OBOA_PROCESSING_DIR" "$OBOA_ERROR_DIR"
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
OBOA uses PostgreSQL for inventory persistence. For local runs outside Compose,
|
|
171
|
+
point OBOA to the PostgreSQL host:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
export OBOA_DDBB_HOST="localhost"
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
ABOA must also be configured when using the default archive delegation client.
|
|
178
|
+
Tests can inject a mock archive client, but production orchestration uses ABOA.
|
|
179
|
+
|
|
180
|
+
## Runtime Configuration
|
|
181
|
+
|
|
182
|
+
OBOA reads JSON and XML runtime resources from the packaged `config` directory by
|
|
183
|
+
default. The packaged resource and schema paths can be overridden when running in
|
|
184
|
+
Docker, tests, or custom deployments.
|
|
185
|
+
|
|
186
|
+
Path environment variables:
|
|
187
|
+
|
|
188
|
+
- `OBOA_RESOURCES_PATH`: directory containing `datamodel.json`, `engine.json`,
|
|
189
|
+
and `orchestrator_configuration.xml`.
|
|
190
|
+
- `OBOA_SCHEMAS_PATH`: directory containing
|
|
191
|
+
`oboa_orchestrator_configuration.xsd`.
|
|
192
|
+
- `OBOA_LOG_PATH`: directory where rotating log files are written.
|
|
193
|
+
|
|
194
|
+
Optional environment variables:
|
|
195
|
+
|
|
196
|
+
- `OBOA_DDBB_HOST`: overrides the PostgreSQL host from `datamodel.json`.
|
|
197
|
+
- `OBOA_LOG_LEVEL`: overrides the log level from `engine.json`.
|
|
198
|
+
- `OBOA_STREAM_LOG`: enables stream logging in addition to the rotating file log.
|
|
199
|
+
- `OBOA_LOG_MAX_BYTES` and `OBOA_LOG_MAX_BACKUP`: override log rotation limits.
|
|
200
|
+
- `OBOA_POLLING_DIR`: overrides `ORCHESTRATION.polling_dir`.
|
|
201
|
+
- `OBOA_POLLING_FREQUENCY`: overrides `ORCHESTRATION.polling_frequency`.
|
|
202
|
+
- `OBOA_DELETE_AFTER_ARCHIVE`: overrides
|
|
203
|
+
`ORCHESTRATION.delete_after_archive`.
|
|
204
|
+
- `OBOA_PROCESSING_DIR`: overrides `ORCHESTRATION.processing_dir`.
|
|
205
|
+
- `OBOA_ERROR_DIR`: overrides `ORCHESTRATION.error_dir`.
|
|
206
|
+
- `OBOA_DAEMON_PID_FILE`: overrides `DAEMON.pid_file`.
|
|
207
|
+
- `OBOA_DAEMON_DATABASE_STARTUP_ATTEMPTS`: number of database readiness checks
|
|
208
|
+
before daemon startup fails.
|
|
209
|
+
- `OBOA_DAEMON_DATABASE_STARTUP_WAIT_SECONDS`: delay between database readiness
|
|
210
|
+
checks.
|
|
211
|
+
- `OBOA_DDBB_STARTUP_ATTEMPTS` and `OBOA_DDBB_STARTUP_WAIT_SECONDS`: accepted
|
|
212
|
+
aliases for the daemon database readiness retry settings.
|
|
213
|
+
|
|
214
|
+
`src/oboa/config/engine.json` configures logging, polling, staging, failed-input
|
|
215
|
+
storage, and daemon startup behavior:
|
|
216
|
+
|
|
217
|
+
```json
|
|
218
|
+
{
|
|
219
|
+
"LOG": {
|
|
220
|
+
"LEVEL": "INFO",
|
|
221
|
+
"MAX_BYTES": 50000000,
|
|
222
|
+
"MAX_BACKUP": 30
|
|
223
|
+
},
|
|
224
|
+
"ORCHESTRATION": {
|
|
225
|
+
"polling_dir": "/oboa_polling",
|
|
226
|
+
"polling_frequency": 30,
|
|
227
|
+
"delete_after_archive": true,
|
|
228
|
+
"processing_dir": "/oboa_processing",
|
|
229
|
+
"error_dir": "/oboa_error"
|
|
230
|
+
},
|
|
231
|
+
"DAEMON": {
|
|
232
|
+
"pid_file": "/tmp/oboa.pid",
|
|
233
|
+
"database_startup_attempts": 30,
|
|
234
|
+
"database_startup_wait_seconds": 2
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Failed input files are moved below the configured error folder using:
|
|
240
|
+
|
|
241
|
+
```text
|
|
242
|
+
<error_dir>/<YEAR>/<MONTH>/<DAY>/<file_name>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
If a file with the same name already exists for the same day, OBOA appends a UUID
|
|
246
|
+
suffix to keep the failed input collision-safe.
|
|
247
|
+
|
|
248
|
+
## Orchestration Configuration XML
|
|
249
|
+
|
|
250
|
+
The default configuration lives at
|
|
251
|
+
`src/oboa/config/orchestrator_configuration.xml`. OBOA validates this file with
|
|
252
|
+
`src/oboa/schemas/oboa_orchestrator_configuration.xsd`.
|
|
253
|
+
|
|
254
|
+
```xml
|
|
255
|
+
<orchestrator_configuration>
|
|
256
|
+
<data group="documents" priority="1">
|
|
257
|
+
<data_mask>*.pdf</data_mask>
|
|
258
|
+
<data_processor>eboa_triggering.py -r -f %F</data_processor>
|
|
259
|
+
</data>
|
|
260
|
+
<data group="images" priority="2">
|
|
261
|
+
<data_mask>*.png</data_mask>
|
|
262
|
+
</data>
|
|
263
|
+
</orchestrator_configuration>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Each `data` rule has:
|
|
267
|
+
|
|
268
|
+
- `group`: file group assigned to matching files and passed to ABOA metadata.
|
|
269
|
+
- `priority`: positive integer used to sort ready files before orchestration.
|
|
270
|
+
Lower values run first.
|
|
271
|
+
- `data_mask`: file-name mask evaluated by OBOA XPath helper functions.
|
|
272
|
+
- `data_processor`: optional executable or command template invoked after
|
|
273
|
+
successful archive delegation.
|
|
274
|
+
|
|
275
|
+
The group `unknown` is reserved. Files that do not match any configured rule are
|
|
276
|
+
orchestrated with file group `unknown` and are processed after matched files.
|
|
277
|
+
|
|
278
|
+
When two ready files match rules with the same priority, OBOA preserves XML rule
|
|
279
|
+
order and then file-name order. OBOA logs the polled files and the priority-sorted
|
|
280
|
+
files on every polling pass.
|
|
281
|
+
|
|
282
|
+
Processor executables may be absolute paths, paths relative to the XML
|
|
283
|
+
configuration file, or command names available in `PATH`. Processor command
|
|
284
|
+
templates may include parameters. `%F` is replaced with the staged processing
|
|
285
|
+
file path before execution:
|
|
286
|
+
|
|
287
|
+
```xml
|
|
288
|
+
<data_processor>eboa_triggering.py -r -f %F</data_processor>
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
For backward compatibility, a processor configured as a bare executable without
|
|
292
|
+
`%F` receives the staged file path as its final argument. Processors also receive
|
|
293
|
+
these environment variables:
|
|
294
|
+
|
|
295
|
+
- `OBOA_FILE_UUID`
|
|
296
|
+
- `OBOA_FILE_PATH`
|
|
297
|
+
- `OBOA_INPUT_PATH`
|
|
298
|
+
- `OBOA_PROCESSING_PATH`
|
|
299
|
+
- `OBOA_FILE_NAME`
|
|
300
|
+
- `OBOA_FILE_GROUP`
|
|
301
|
+
- `OBOA_CONFIGURATION_UUID`
|
|
302
|
+
|
|
303
|
+
## Command Line Tools
|
|
304
|
+
|
|
305
|
+
The package installs these console commands:
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
oboa_init.py [-f /path/to/oboa_data_model.sql] [-y]
|
|
309
|
+
oboa_configure.py [--configuration /path/to/orchestrator_configuration.xml]
|
|
310
|
+
oboa_orchestrate.py --file /path/to/file [--configuration XML] [--delete-after-archive | --keep-input] [--processing-dir DIR]
|
|
311
|
+
oboa_poll.py [--once] [--polling-dir DIR] [--polling-frequency SECONDS] [--configuration XML] [--delete-after-archive | --keep-input] [--processing-dir DIR]
|
|
312
|
+
oboa_daemon.py {start|stop|restart|status} [--pid-file FILE] [--foreground] [--polling-dir DIR] [--polling-frequency SECONDS] [--configuration XML]
|
|
313
|
+
oboa_query.py (--files | --configurations | --operations) [filters]
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Common examples:
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
oboa_init.py -y
|
|
320
|
+
oboa_configure.py --configuration /data/config/orchestrator_configuration.xml
|
|
321
|
+
oboa_orchestrate.py --file /data/incoming/report.txt --keep-input
|
|
322
|
+
oboa_poll.py --once --polling-dir /data/incoming
|
|
323
|
+
oboa_poll.py --polling-dir /data/incoming --polling-frequency 5
|
|
324
|
+
oboa_daemon.py start --foreground --polling-dir /data/incoming
|
|
325
|
+
oboa_daemon.py status
|
|
326
|
+
oboa_daemon.py stop
|
|
327
|
+
oboa_query.py --files --name "%.txt" --order-by reception_date --descending
|
|
328
|
+
oboa_query.py --operations --operation archive --status 10
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
`oboa_query.py` supports these entities:
|
|
332
|
+
|
|
333
|
+
- `--files`: query `orchestrated_files`.
|
|
334
|
+
- `--configurations`: query `orchestration_configurations`.
|
|
335
|
+
- `--operations`: query failed operation rows in `orchestration_operations`.
|
|
336
|
+
|
|
337
|
+
Common query controls include `--uuid`, `--name`, `--path`, `--file-group`,
|
|
338
|
+
`--operation`, `--status`, `--active`, `--archived`, `--processed`,
|
|
339
|
+
`--selection`, `--order-by`, `--descending`, `--group-by`, `--limit`, and
|
|
340
|
+
`--offset`. Run any command with `--help` for the exact supported options.
|
|
341
|
+
|
|
342
|
+
## Python API
|
|
343
|
+
|
|
344
|
+
Use `Engine` for mutating orchestration operations and `Query` for read-only
|
|
345
|
+
inventory access.
|
|
346
|
+
|
|
347
|
+
```python
|
|
348
|
+
from oboa.engine.engine import Engine
|
|
349
|
+
from oboa.engine.query import Query
|
|
350
|
+
|
|
351
|
+
engine = Engine()
|
|
352
|
+
try:
|
|
353
|
+
engine.configure_orchestrator("/data/config/orchestrator_configuration.xml")
|
|
354
|
+
row = engine.orchestrate_file("/data/incoming/report.txt")
|
|
355
|
+
finally:
|
|
356
|
+
engine.close_session()
|
|
357
|
+
|
|
358
|
+
query = Query()
|
|
359
|
+
try:
|
|
360
|
+
files = query.get_orchestrated_files(
|
|
361
|
+
names={"filter": "%.txt", "op": "like"},
|
|
362
|
+
order_by={"field": "reception_date", "descending": True},
|
|
363
|
+
)
|
|
364
|
+
failures = query.get_orchestration_operations(
|
|
365
|
+
operations={"filter": "archive", "op": "like"}
|
|
366
|
+
)
|
|
367
|
+
finally:
|
|
368
|
+
query.close_session()
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Important write-side methods include `configure_orchestrator`,
|
|
372
|
+
`orchestrate_file`, `poll_once`, `run_polling_loop`, `run_daemon`,
|
|
373
|
+
`validate_daemon_startup`, `prepare_processing_file`, and
|
|
374
|
+
`move_to_error_folder`.
|
|
375
|
+
|
|
376
|
+
Important query methods include `get_active_orchestration_configuration`,
|
|
377
|
+
`get_orchestrated_files`, `get_orchestration_configurations`, and
|
|
378
|
+
`get_orchestration_operations`.
|
|
379
|
+
|
|
380
|
+
## Operation Flow Schematics
|
|
381
|
+
|
|
382
|
+
### Operations Overview
|
|
383
|
+
|
|
384
|
+

|
|
385
|
+
|
|
386
|
+
### Configuration Activation
|
|
387
|
+
|
|
388
|
+

|
|
389
|
+
|
|
390
|
+
### Daemon Polling And Priority
|
|
391
|
+
|
|
392
|
+

|
|
393
|
+
|
|
394
|
+
### File Orchestration
|
|
395
|
+
|
|
396
|
+

|
|
397
|
+
|
|
398
|
+
## Data Model
|
|
399
|
+
|
|
400
|
+
The DDBB model, stored in `src/oboa/datamodel/oboa_data_model.dbm`, is built
|
|
401
|
+
using pgModeler. The tool is then used to generate the SQL instructions, stored
|
|
402
|
+
in `src/oboa/datamodel/oboa_data_model.sql`, to initialize the DDBB.
|
|
403
|
+
|
|
404
|
+

|
|
405
|
+
|
|
406
|
+
Main inventory tables:
|
|
407
|
+
|
|
408
|
+
- `orchestration_configurations`: active and historical XML configuration
|
|
409
|
+
snapshots.
|
|
410
|
+
- `orchestrated_files`: input file inventory, matched group, archive status,
|
|
411
|
+
processor status, reception timestamp, and configuration UUID.
|
|
412
|
+
- `orchestration_operations`: failed operation records for configuration,
|
|
413
|
+
polling, orchestration, archive, processing, and daemon-related failures.
|
|
414
|
+
|
|
415
|
+
## Development Layout
|
|
416
|
+
|
|
417
|
+
- `src/oboa/datamodel`: SQLAlchemy model, database configuration, exported SQL,
|
|
418
|
+
and pgModeler model.
|
|
419
|
+
- `src/oboa/engine`: orchestration, archive delegation, query, daemon,
|
|
420
|
+
configuration, XPath, and CLI logic.
|
|
421
|
+
- `src/oboa/processors`: executable data-processor helpers.
|
|
422
|
+
- `src/oboa/config`: default runtime configuration.
|
|
423
|
+
- `src/oboa/schemas`: bundled OBOA XML schemas.
|
|
424
|
+
- `src/oboa/scripts`: console script entry points and database initialization
|
|
425
|
+
helpers.
|
|
426
|
+
- `src/tests`: pytest-based test suite and persistent test inputs.
|
|
427
|
+
- `development_plans`: design notes, requirements, and operation flow details.
|
|
428
|
+
- `doc/fig`: data model and operation-flow diagrams.
|
|
429
|
+
|
|
430
|
+
## Tests
|
|
431
|
+
|
|
432
|
+
Install the test extra and run the suite from the repository root:
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
python -m pip install -e ".[tests]"
|
|
436
|
+
export OBOA_RESOURCES_PATH="$PWD/src/oboa/config"
|
|
437
|
+
export OBOA_SCHEMAS_PATH="$PWD/src/oboa/schemas"
|
|
438
|
+
export OBOA_LOG_PATH="$PWD/log"
|
|
439
|
+
export OBOA_POLLING_DIR="/tmp/oboa_polling"
|
|
440
|
+
export OBOA_PROCESSING_DIR="/tmp/oboa_processing"
|
|
441
|
+
export OBOA_ERROR_DIR="/tmp/oboa_error"
|
|
442
|
+
mkdir -p "$OBOA_LOG_PATH" "$OBOA_POLLING_DIR" "$OBOA_PROCESSING_DIR" "$OBOA_ERROR_DIR"
|
|
443
|
+
python -m pytest src/tests
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
The integration tests that exercise OBOA through ABOA are skipped when the ABOA
|
|
447
|
+
package is not available.
|
|
448
|
+
|
|
449
|
+
## Publishing To PyPI
|
|
450
|
+
|
|
451
|
+
See [the publishing guide](https://github.com/Daniel-Brosnan-Blazquez/oboa/blob/main/doc/publishing.md)
|
|
452
|
+
for local build checks, PyPI Trusted Publisher setup, and the GitHub release
|
|
453
|
+
workflow. Package metadata lives in `pyproject.toml`; the release version is
|
|
454
|
+
read from `src/oboa/__init__.py`.
|