-
Notifications
You must be signed in to change notification settings - Fork 0
/
README
180 lines (118 loc) · 6.17 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
Interfacing to BCMS CTS
=======================
The British Cattle Movement Service is a division of the UK Rural Payments
Agency. They run a database of all British bovines, known as the Cattle
Tracing System. Farmers record all births, deaths, arrivals and departures,
and can access this information for their animals.
As well as a clunky web interface, CTS has an XML-over-HTTP API. This is a
hilarious showcase of enterprise mediocrity: ugly, inconsistent, mixed-case
tag/attribute names in an XML soup that is base64-encoded and then wrapped
in another XML layer. Would you like an AbstractSingletonProxyFactoryBean
with that?
Implementation highlights include multi-second latency from virus-scanning
the base64 payload before parsing it as XML, and (very) asynchronous
responses to the smallest database modifications. The best one can do in a
client interface is to abstract away some of the ugliness.
Each farmer is automatically issued with a CTS Web Services username and
password, which software needs to authenticate to CTWS. The username is
typically three groups of three digits separated by hyphens in the format
nnn-nnn-nnn. It is not the same as the CTS Online web login.
As a single farmer can have access to multiple holdings, the specific CPH
number must also be provided with requests to prevent ambiguity.
Separately, the DEFRA Data Transfer Service expects software to identify
itself with a fixed username and password. These credentials self-evidently
have no useful security properties as they need to ship with programs in
plaintext-equivalent form, but this flavour of idiocy afflicts a number of
UK public-sector APIs.
Acquiring DDTS credentials is left as an exercise for the user. You can
obtain them officially by jumping through some simple hoops to demonstrate
compliant use of the API on a test server, or extract them from other
software, or just man-in-the-middle any CTWS client's https connection to
read them out.
Installation and configuration
------------------------------
A single Python 3.x script 'cts' is provided. Ensure the #! path is correct
for your system before copying it to a directory on your path.
The DDTS (software) username/password, CTWS (farmer) username/password and
the holding number must be configured either in environment variables or in
the config hash at the top of the 'cts' script.
To use the environment, export DDTSAUTH in the format USERNAME:PASSWORD,
CTWSAUTH in the format USERNAME:PASSWORD, and HOLDING in the format
CC/PPP/HHHH or CC/PPP/HHHH-NN if you have multiple sub-locations associated
with your holding. Each setting is only read from the environment if it is
not set in the config hash in the script.
Listing animals
---------------
To list animals on the holding, run
cts list
This outputs lines for each animal in the space-separated format
TAG BREED SEX BORN ARRIVED
where
- TAG is the registered ear tag, e.g. 'UK701453700119';
- BREED is the breed code, e.g. 'LIMX' or 'WAX';
- SEX is a single character 'M' or 'F';
- BORN is the date of birth in the format YYYY-MM-DD;
- ARRIVED is the arrival date on the holding in the format YYYY-MM-DD.
This format is chosen to make correct shell, awk or sed one-liners simple.
There are no escape characters or line-continuations, no optional or
potentially empty fields, no fields allowing whitespace, and the date
format can be compared lexicographically without parsing.
For example, to list the group who moved on to the holding on 2021-03-01:
cts list | awk '$5 == "2021-03-01" { print $0 }'
or to get tags and dates of birth for all heifers/cows born before 2019:
cts list | awk '$3 == "F" && $4 < "2019-01-01" { print $1, $4 }'
or to generate a full CSV file compatible with spreadsheet software:
cts list | tr ' ' ','
Listing movement history
------------------------
To list the movement history of animals on the holding, run
cts history [TAG]...
The list of ear tags can be given as command arguments or on stdin, with one
tag per line. The first whitespace-separated word is assumed to be the ear
tag; any other words on each line are ignored.
This outputs lines of the form
TAG DATE LOCATION TYPE
where
- TAG is the registered ear tag, e.g. 'UK701453700119';
- DATE is the movement date in the format YYYY-MM-DD;
- LOCATION is the movement location, e.g. '35/166/0188';
- TYPE describes the moment: 'birth', 'death', 'off' or 'on'.
If an animal is not found on the holding, a single line of the form
TAG not found
is printed instead. Unfortunately, CTWS fails to distinguish tags that do
not exist from valid animals that have moved to another holding, despite
this information being available in the web interface. However, history is
correctly returned for animals that died on the holding.
Reporting movements
-------------------
To report a movement off the holding, run
cts move off YYYY-MM-DD [TAG]...
where YYYY-MM-DD is the date of the movement. The list of ear tags can be
given as command arguments or on stdin, with one tag per line. The first
whitespace-separated word is assumed to be the ear tag; any other words on
each line are ignored.
Similarly, to report a movement onto the holding, use
cts move on YYYY-MM-DD [TAG]...
and to report deaths, use
cts death YYYY-MM-DD [TAG]...
CTS implements these operations asynchronously: clients submit a request,
get a receipt in return, then call back with the receipt number to retrieve
validation results or an error. In practice, results are usually available
immediately, so for ease of use, cts move combines both operations. It will
automatically retry when requests are backlogged but this is rare.
The receipt number, any validation errors, and the numbers of accepted and
rejected movements are reported on stdout.
Checking for queries
--------------------
To check for queried animals or movements, run
cts queries
This will report any queries with lines in the format
animal TAG BREED SEX BORN ARRIVED
or
move TAG TYPE YYYY-MM-DD
for queried animals and movements respectively. The output should normally
be empty, indicating no problems.
Copying
-------
This software was written by Chris Webb <[email protected]> and is
distributed as Free Software under the terms of the MIT license in COPYING.