Is there presently a way to run a report query (and thus generate a label or report) for a record (or set of records) via the API?
I imagine not, because the report runner doesn’t have a unique URL response and the reports do not persist on the server after the report runner is closed, right?
Technically there is an API for it, via POST /report_runner/run/, since Specify just POSTs a form to this endpoint with report (JRXML), query (JSON, incl. recordSetId for sets, or an id-filter for single records), and parameters (as a JSON object). The response is the PDF itself, but it was designed to always be triggered by Specify alone and not another source.
You’re right that there is no persistence since the PDF is rendered on the fly each time, so it isn’t really stored anywhere long-term. There’s also not a unique URL really, since the endpoint’s body is the PDF.
It’s really not designed to be used since there’s no API auth on this endpoint. To use it, you’d need to replicate the whole stack (session, auth, CSRF token) and send the expected request.
If anyone is planning on using Specify’s endpoint for this (/report_runner/run/), here’s some additional information that should be helpful.
The /report_runner/run/ endpoint in Specify 7 is undocumented and largely considered “internal” by the Specify team.
You are free to use it in your own projects, but it might be subject to change in the future.
Use it at your own risk
The following is the location within the Specify7 code where the request is handled.
If you’re able to read and parse Python code, this is the best place to learn how it works:
If you plan on using the Report Runner directly, below is the relevant code that handles the request (written in Java)
The Report Runner is completely stateless, meaning it has no persistence and no concept of which Queries map to which Reports. The physical report and associated results which act as the report’s “data source” have to be handed to the Report Runner for each request.
For the Specify 7 /report_runner/run/ POST endpoint, the request body should be in x-www-form-urlencoded format and have the three key+value pairs aforementioned by Grant:
query
A serialized/stringified JSON representation of the Query that will be run by Specify to retrieve the result to be passed to the Report Runner
report
A serialized/stringified XML representation of the report (i.e., the JRXML of the report you want to run, as a string)
parameters
The report parameters (if any) in a serialized JSON format
A report parameter is a non-QueryBuilder field value mapped to a name that is entered by the user before a report is ran
These would be on your reports with something like parameter[isForPrompting="true"]
Most reports probably won’t have parameters, but this key+value pair is still required
The Specify 7 endpoint does make sure the executing user has the correct permissions to execute reports and read the tables present in the serialized Query.
The Specify 7 backend can respond in three different ways:
With a 200 status code, a text/plain Content Type, and the text The report query returned no results. if the serialized Query did not return any results
With a 200 status code, an application/pdf Content Type, and the resulting PDF as conent
With a 500 status code and an exception message if the Report Runner was not able to correctly process the report