diff --git a/docs/source/oclapi/apireference/exportapi.md b/docs/source/oclapi/apireference/exportapi.md index 48354ce..1193922 100644 --- a/docs/source/oclapi/apireference/exportapi.md +++ b/docs/source/oclapi/apireference/exportapi.md @@ -1,7 +1,7 @@ # Export API ## Overview -The API provides an `export` endpoint for creating, fetching, and deleting a cached export of repository version. Exports are automatically generated upon creation of a new source or collection version and cached, so requesting an export is a quick operation even for a large repository. The recommended method for determining if an export is available after creating a new repository version is by checking the status code of a `HEAD` request to the export, eg `HEAD /[:ownerType/]:owner/:repoType/:repo/:repoVersion/export/`. The status code is `302` if the export is ready for download, `208` if it is still being created, or `204` if there is no export. Don't follow the redirect when checking availability (for example, use `curl -I` without `-L`): the signed URL is valid only for `GET`. Note that the old method of determining when an export is available is by checking the `is_processing` flag of the repository version, which is set to `False` after processing of the new repository version is complete. This method is still correct, but if you only need an export and not a fully processed repository version, then the Export API method is more performant as creating and uploading an export is a much faster operation. +The API provides an `export` endpoint for creating, fetching, and deleting a cached export of repository version. Exports are automatically generated upon creation of a new source or collection version and cached, so requesting an export is a quick operation even for a large repository. The recommended method for determining if an export is available after creating a new repository version is by checking the status code of a `HEAD` request to the export, eg `HEAD /[:ownerType/]:owner/:repoType/:repo/:repoVersion/export/`. The status code is `302` if the export is ready for download, `208` if it is still being created, or `204` if there is no export. Don't follow the redirect when checking availability (for example, use `curl -I` without `-L`): the signed URL is valid only for `GET`. The repository version's `is_processing` flag is not a reliable signal for this: it turns `False` when processing of the new version ends, even if creating the export failed. Use the Export API to find out whether an export exists. The Export API enables a client to manage cached exports manually for special situations, such as triggering the creation of a new export that did not get cached correctly. The filename of the export contains the export's `lastUpdated` timestamp, which can be used to fetch the diff between an export and the current state of a source or collection. A `GET` request to the export endpoint redirects to a signed download URL, and the download carries the filename in its `Content-Disposition` response header. @@ -102,9 +102,10 @@ Status: 404 Not Found ## Create an export of a repository version -* Create an export file for the specified repository version; if it already exists, no action is taken +* Create an export file for the specified repository version. If one already exists, no action is taken unless `force=true` is passed, which creates it again. ``` POST /[:ownerType/]:owner/:repoType/:repo/:repoVersion/export/ +POST /[:ownerType/]:owner/:repoType/:repo/:repoVersion/export/?force=true ``` * Notes * `:repoVersion` is required. `HEAD` exports are available only to staff, superusers and the repository's owner (the owning user, or members of the owning organization); other users who can see the repository get `405 Not Allowed`. @@ -117,17 +118,28 @@ POST /orgs/CIEL/sources/CIEL/v2.2/export/ ``` ### Response -* If no export file already exists and processing is initiated: +* The API checks these cases in order: an export being created (`208`) takes precedence over `force` and `noRedirect`, and `force=true` takes precedence over `noRedirect`. +* If an export file is currently being created: +``` +Status: 208 Already Reported +``` +* If no export file already exists (or `force=true` was passed) and processing is initiated: ``` Status: 202 Accepted ``` -* If an export file is currently being processed: +* If the same export job is already queued: ``` Status: 409 Conflict ``` -* If the export file already exists (use GET to download it): +* If the export file already exists, the response points to the export endpoint; download it with a GET to the same export URL you posted to. For a `HEAD` export, the `URL` header leaves out `HEAD/`, so use the URL you posted to rather than the header. ``` -Status: 200 OK +Status: 303 See Other +Response Header: +URL: /[:ownerType/]:owner/:repoType/:repo/:repoVersion/export/ +``` +* If the export file already exists and `noRedirect=true` was passed: +``` +Status: 204 No Content ``` * If the request is otherwise invalid - return the appropriate error code @@ -140,22 +152,27 @@ DELETE /[:ownerType/]:owner/:repoType/:repo/:repoVersion/export/ ``` * Notes * `HEAD` exports are available only to staff, superusers and the repository's owner (the owning user, or members of the owning organization); other users who can see the repository get `405 Not Allowed`. - * The passed authorization token must have administrative access to the repository in order to delete the export file + * The passed authorization token must have administrative access to the repository (staff, superusers or the repository's owner) in order to delete the export file; otherwise the API returns `403 Forbidden`. + * DELETE removes the export cached under the version's current `lastUpdated`. An export of the same version cached under an earlier timestamp isn't removed, and GET may still return it. ### Example -* Create the export file for v2.2 of the CIEL source +* Delete the export file for v2.2 of the CIEL source ``` DELETE /orgs/CIEL/sources/CIEL/v2.2/export/ ``` ### Response -* If the file exists, it is deleted with 204 +* If the file exists, it is deleted: +``` +Status: 204 No Content +``` +* If the file does NOT exist: ``` -Status: 204 Success +Status: 404 Not Found ``` -* If the file does NOT exist +* If the user doesn't have administrative access to the repository: ``` -Status: 404 No Content +Status: 403 Forbidden ``` * If the request is otherwise invalid - return the appropriate error code diff --git a/docs/source/oclapi/apireference/other/subscriptions.md b/docs/source/oclapi/apireference/other/subscriptions.md index c5ea0c5..cfea4f2 100644 --- a/docs/source/oclapi/apireference/other/subscriptions.md +++ b/docs/source/oclapi/apireference/other/subscriptions.md @@ -19,11 +19,11 @@ _For the first synchronization, fetch the most recent export of a **released** s ``` GET /orgs/[:org]/sources/[:source]/latest/ ``` -* Retrieve the filename of full export for the latest released source version, which is returned in the response header as the `exportURL` field. Note that if the export file does not already exist, is still being processed, or is invalid, the API returns a specific status or error code and the export can be retrieved later after an appropriate interval. Refer to [[Export-API]] for more info on this request. +* Request the full export of the latest released source version. If the export is ready, the API responds `302 Found` and its `Location` response header holds a signed URL to download the file. If the export is still being created, the API returns `208 Already Reported`; request it again after an appropriate interval. If there is no export, the API returns `204 No Content`; create one with `POST /orgs/[:org]/sources/[:source]/[:sourceVersion]/export/`, then request it again once it is ready. Refer to [[Export-API]] for more info on this request. ``` GET /orgs/[:org]/sources/[:source]/[:sourceVersion]/export/ ``` -* Download the export file from the `exportURL` (returns a compressed tar file of the JSON). Record the `lastUpdated` timestamp which is part of the filename. Refer to [[Export-API]] for more info on this request. Note that the `exportURL` is designed to be used only once and it expires after a set time limit -- to ensure that the `exportURL` works correctly, use it immediately and request another `exportURL` each time you want to download an export file. +* Download the export file from the signed URL (a zip file of the JSON); most HTTP clients follow the redirect automatically. Record the `lastUpdated` timestamp, which is the last part of the filename (e.g. `2026-09-30_123456`), and convert it to ISO 8601 (`2026-09-30T12:34:56Z`) for use with `updatedSince`. Refer to [[Export-API]] for more info on this request. Note that the signed URL expires after a set time limit -- use it immediately, and request the export again each time you want to download an export file. * Fetch all updates to the source that are more recent than the export using the `lastUpdated` timestamp (e.g. ISO 8601 timestamp (e.g. `2011-11-16T14:26:15Z`)). There are two methods for doing this: * Use a combination of the `limit` and `offset` parameters to iteratively retrieve results until fewer than `limit` results are returned. Note that the standard paging response headers (num_returned, num_found, offset, page, next_url, prev_url) are not supported at the source endpoint, and paging must be managed by the client. ``` @@ -46,9 +46,9 @@ GET /orgs/[:org]/sources/[:source]/?includeMappings=true&includeConcepts=true&in * A subscription client, such as the OpenMRS OCL Subscription module, should be configured with the source URL (e.g. `/orgs/CIEL/sources/CIEL/), an API token, and a synchronization schedule (e.g. weekly or monthly) * On the first synchronization: * Subscription client will request details on the most recent released source version: `GET /orgs/CIEL/sources/CIEL/latest/` - * Subscription client will request the export file URL of the most recent released source version, which will return the `exportURL` in the response header: `GET /orgs/CIEL/sources/CIEL/[:sourceVersion]/export/` - * Note that if the export file is not ready, the subscription client will need to request the export file again after an appropriate interval - * Subscription client will download the export file from `exportURL`, which is returned as a compressed tar of the JSON results -- the `exportURL` can be discarded, as it is re-generated for each request + * Subscription client will request the export of the most recent released source version, which redirects to a signed download URL (the `Location` response header): `GET /orgs/CIEL/sources/CIEL/[:sourceVersion]/export/` + * Note that if the export file is not ready (`208`), the subscription client will need to request the export file again after an appropriate interval; if there is no export (`204`), it must first create one with a `POST` to the same URL + * Subscription client will download the export file from the signed URL, which is returned as a zip of the JSON results -- the signed URL can be discarded, as it is re-generated for each request * Subscription client will decompress the file and process the results * Subscription client may then request any changes to the source that occurred after the `lastUpdated` timestamp of the export file: `GET /orgs/CIEL/sources/CIEL/?includeConcepts=true&includeMappings=true&includeRetired=true&updatedSince=[:lastUpdated]` -- these results should be processed in the same manner as above; the `lastUpdated` date should be stored for subsequent synchronizations * On subsequent synchronizations: @@ -255,7 +255,7 @@ POST /orgs/MyOrg/sources/MySource/v1.0/export/
  • Make changes to concepts and mappings - these will be saved to source version `v1.1`
  • Fetch the export and changes made since the export