diff --git a/docs/spec/openapi.yaml b/docs/spec/openapi.yaml index 826fdeb..dc734a9 100644 --- a/docs/spec/openapi.yaml +++ b/docs/spec/openapi.yaml @@ -1,325 +1,679 @@ -components: - schemas: - AnnotationUpdateRequest: - properties: - data: - type: object - key: - type: string - session: - type: string - required: - - data - - key - - session - title: AnnotationUpdateRequest - type: object - KnowledgeSourcesResponse: - properties: - sources: - items: - type: string - type: array - required: - - sources - title: KnowledgeSourcesResponse - type: object - MakerData: - properties: - commit: - oneOf: - - type: string - - type: 'null' - force: - oneOf: - - type: boolean - - type: 'null' - manifest: - type: string - source: - type: string - required: - - manifest - - source - title: MakerData - type: object - MakerLogResponse: - properties: - id: - oneOf: - - type: integer - - type: 'null' - log: - type: string - pid: - oneOf: - - type: integer - - type: 'null' - stamp: - oneOf: - - type: string - - type: 'null' - status: - type: string - required: - - log - - status - title: MakerLogResponse - type: object - MakerResponse: - properties: - commit: - oneOf: - - type: string - - type: 'null' - id: - oneOf: - - type: integer - - type: 'null' - pid: - oneOf: - - type: integer - - type: 'null' - source: - type: string - status: - type: string - required: - - source - - status - title: MakerResponse - type: object - MakerStatus: - properties: - id: - oneOf: - - type: integer - - type: 'null' - pid: - oneOf: - - type: integer - - type: 'null' - status: - type: string - required: - - status - title: MakerStatus - type: object - ParameterChoiceDict: - properties: - label: - type: string - value: - type: string - required: - - label - - value - title: ParameterChoiceDict - type: object - ParameterDefinitionDict: - properties: - choices: - items: - $ref: '#/components/schemas/ParameterChoiceDict' - type: array - column: - type: string - default: - type: string - label: - type: string - multiple: - type: boolean - type: - type: string - required: - - column - - label - title: ParameterDefinitionDict - type: object - QueryData: - properties: - params: - oneOf: - - items: - type: string - type: array - - type: 'null' - sql: - type: string - required: - - sql - title: QueryData - type: object - QueryDefinitionDict: - properties: - description: - type: string - id: - type: string - label: - type: string - parameters: - items: - $ref: '#/components/schemas/ParameterDefinitionDict' - type: array - results: - items: - $ref: '#/components/schemas/ResultDefinitionDict' - type: array - required: - - id - - label - - results - title: QueryDefinitionDict - type: object - QueryDefinitionSummary: - properties: - description: - type: string - id: - type: string - label: - type: string - required: - - id - - label - title: QueryDefinitionSummary - type: object - QueryError: - properties: - error: - type: string - required: - - error - title: QueryError - type: object - QueryParameter: - properties: - column: - type: string - negate: - type: boolean - value: - oneOf: - - type: string - - items: - type: string - type: array - required: - - column - - value - title: QueryParameter - type: object - QueryRequest: - properties: - limit: - type: integer - order: - items: - type: string - type: array - parameters: - items: - $ref: '#/components/schemas/QueryParameter' - type: array - query_id: - type: string - required: - - query_id - title: QueryRequest - type: object - QueryResultRows: - properties: - keys: - items: - type: string - type: array - values: - items: - items: - type: string - type: array - type: array - required: - - keys - - values - title: QueryResultRows - type: object - QueryResults: - properties: - query_id: - type: string - results: - $ref: '#/components/schemas/QueryResultRows' - required: - - query_id - - results - title: QueryResults - type: object - ResultDefinitionDict: - properties: - key: - type: string - label: - type: string - type: - type: string - required: - - key - title: ResultDefinitionDict - type: object info: title: Flatmap Server Web API - version: 1.5.2 + version: 1.12.0 openapi: 3.1.0 +servers: +- url: '' paths: - /: + /annotator/annotation: + get: + summary: AnnotatorAnnotation + description: Retrieve an annotation by ID, passed as the `annotation` query + parameter. Requires `key` and `session` query parameters from [GET /annotator/authenticate](#get-/annotator/authenticate). + operationId: AnnotatorAnnotationAnnotatorAnnotation + responses: + '200': + description: Request fulfilled, document follows + headers: {} + content: + application/json: + schema: + type: object + deprecated: false + post: + summary: AnnotatorAddAnnotation + description: Create an annotation. Requires `key` and `session` obtained from + [GET /annotator/authenticate](#get-/annotator/authenticate), and an authenticated + user with update permission. + operationId: AnnotatorAnnotationAnnotatorAddAnnotation + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AnnotationUpdateRequest' + required: true + responses: + '201': + description: Document created, URL follows + headers: {} + content: + application/json: + schema: + oneOf: + - type: object + - {} + '400': + description: Bad request syntax or unsupported method + content: + application/json: + schema: + properties: + status_code: + type: integer + detail: + type: string + extra: + additionalProperties: {} + type: + - 'null' + - object + - array + type: object + required: + - detail + - status_code + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} + deprecated: false + /annotator/items: + get: + summary: AnnotatorAnnotatedItems + description: Retrieve annotated item IDs for a resource. Requires `key` and + `session` query parameters from [GET /annotator/authenticate](#get-/annotator/authenticate). + operationId: AnnotatorItemsAnnotatorAnnotatedItems + responses: + '200': + description: Request fulfilled, document follows + headers: {} + content: + application/json: + schema: + type: object + deprecated: false + /annotator/annotation/{id}: + get: + summary: AnnotatorAnnotationById + description: Retrieve an annotation by ID. Requires `key` and `session` query + parameters from [GET /annotator/authenticate](#get-/annotator/authenticate). + operationId: AnnotatorAnnotationIdAnnotatorAnnotationById + parameters: + - name: id + in: path + schema: + type: string + description: The annotation ID to retrieve. + description: The annotation ID to retrieve. + required: true + deprecated: false + responses: + '200': + description: Request fulfilled, document follows + headers: {} + content: + application/json: + schema: + type: object + '400': + description: Bad request syntax or unsupported method + content: + application/json: + schema: + properties: + status_code: + type: integer + detail: + type: string + extra: + additionalProperties: {} + type: + - 'null' + - object + - array + type: object + required: + - detail + - status_code + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} + deprecated: false + /annotator/annotations: + get: + summary: AnnotatorAnnotations + description: Retrieve annotations for a resource item. Requires `key` and `session` + query parameters from [GET /annotator/authenticate](#get-/annotator/authenticate). + operationId: AnnotatorAnnotationsAnnotatorAnnotations + responses: + '200': + description: Request fulfilled, document follows + headers: {} + content: + application/json: + schema: + items: + type: object + type: array + deprecated: false + /annotator/authenticate: + get: + summary: AnnotatorAuthenticate + description: Authenticate a Pennsieve API key and create an annotator session. + Pass `key` as a query parameter; use the returned `session` with subsequent + annotator requests. + operationId: AnnotatorAuthenticateAnnotatorAuthenticate + responses: + '200': + description: Request fulfilled, document follows + headers: {} + content: + application/json: + schema: + oneOf: + - type: object + - {} + deprecated: false + /annotator/download: + get: + summary: AnnotatorDownload + description: 'Download all annotations. Requires `Authorization: Bearer TOKEN`.' + operationId: AnnotatorDownloadAnnotatorDownload + responses: + '200': + description: Request fulfilled, document follows + headers: {} + content: + application/json: + schema: + items: + type: object + type: array + deprecated: false + /annotator/features: + get: + summary: AnnotatorFeatures + description: Retrieve annotation features for a resource. Requires `key` and + `session` query parameters from [GET /annotator/authenticate](#get-/annotator/authenticate). + operationId: AnnotatorFeaturesAnnotatorFeatures + responses: + '200': + description: Request fulfilled, document follows + headers: {} + content: + application/json: + schema: + type: object + deprecated: false + /annotator/update: + post: + summary: AnnotatorUpdateStatus + description: Update an annotation status. Requires `key` and `session` obtained + from [GET /annotator/authenticate](#get-/annotator/authenticate), and an authenticated + user with update permission. + operationId: AnnotatorUpdateAnnotatorUpdateStatus + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AnnotationUpdateRequest' + required: true + responses: + '201': + description: Document created, URL follows + headers: {} + content: + application/json: + schema: + oneOf: + - type: object + - {} + '400': + description: Bad request syntax or unsupported method + content: + application/json: + schema: + properties: + status_code: + type: integer + detail: + type: string + extra: + additionalProperties: {} + type: + - 'null' + - object + - array + type: object + required: + - detail + - status_code + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} + deprecated: false + /annotator/unauthenticate: + get: + summary: AnnotatorUnauthenticate + description: Delete an annotator session. Pass its `session` value as a query + parameter. + operationId: AnnotatorUnauthenticateAnnotatorUnauthenticate + responses: + '200': + description: Request fulfilled, document follows + headers: {} + content: + application/json: + schema: + type: object + deprecated: false + /competency/query: + post: + summary: CompetencyQuery + description: Execute a competency query. The required parameters depend on the + selected query_id. See [GET /competency/queries/{query_id}](#get-/competency/queries/-query_id-) + for parameter definitions. See [GET /competency/queries/](#get-/competency/queries) + for the list of available queries. + operationId: CompetencyQueryCompetencyQuery + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/QueryRequest' + required: true + responses: + '201': + description: Document created, URL follows + headers: {} + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/QueryResults' + - $ref: '#/components/schemas/QueryError' + '400': + description: Bad request syntax or unsupported method + content: + application/json: + schema: + properties: + status_code: + type: integer + detail: + type: string + extra: + additionalProperties: {} + type: + - 'null' + - object + - array + type: object + required: + - detail + - status_code + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} + deprecated: false + /competency/schema-version: get: + summary: CompetencySchemaVersion + description: Retrieve version details for the competency schema. + operationId: CompetencySchemaVersionCompetencySchemaVersion + responses: + '200': + description: Request fulfilled, document follows + headers: {} + content: + application/json: + schema: + additionalProperties: + oneOf: + - type: string + - type: 'null' + type: object deprecated: false - operationId: FlatmapMaps + /competency/queries/{query_id}: + get: + summary: CompetencyQueryDefinition + description: Retrieve a competency query definition by ID. + operationId: CompetencyQueriesQueryIdCompetencyQueryDefinition + parameters: + - name: query_id + in: path + schema: + type: string + description: The ID of the competency query. See [GET /competency/queries/](#get-/competency/queries) + for the list of available queries. + examples: + - '1' + description: The ID of the competency query. See [GET /competency/queries/](#get-/competency/queries) + for the list of available queries. + required: true + deprecated: false + examples: + query_id-example-1: + summary: Example query ID + value: '1' responses: '200': + description: Request fulfilled, document follows + headers: {} content: application/json: schema: - type: array + $ref: '#/components/schemas/QueryDefinitionDict' + '400': + description: Bad request syntax or unsupported method + content: + application/json: + schema: + properties: + status_code: + type: integer + detail: + type: string + extra: + additionalProperties: {} + type: + - 'null' + - object + - array + type: object + required: + - detail + - status_code + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} + deprecated: false + /competency/queries: + get: + summary: CompetencyQueryDefinitions + description: Retrieve all available competency query definitions. + operationId: CompetencyQueriesCompetencyQueryDefinitions + responses: + '200': description: Request fulfilled, document follows headers: {} - summary: FlatmapMaps - /annotator/annotation: + content: + application/json: + schema: + items: + $ref: '#/components/schemas/QueryDefinitionSummary' + type: array + deprecated: false + /flatmap/{map_uuid}/annotations: get: + summary: FlatmapAnnotation + description: Retrieve flatmap annotations by map UUID. + operationId: FlatmapMapUuidAnnotationsFlatmapAnnotation + parameters: + - name: map_uuid + in: path + schema: + type: string + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap + listing endpoint. See [GET /](#get-/) for the list of available flatmaps. + examples: + - a5139708-c35a-5ba5-b8e8-a7ce6559224a + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap listing + endpoint. See [GET /](#get-/) for the list of available flatmaps. + required: true + deprecated: false + examples: + map_uuid-example-1: + summary: Example UUID + value: a5139708-c35a-5ba5-b8e8-a7ce6559224a + responses: + '200': + description: Request fulfilled, document follows + headers: {} + content: + application/json: + schema: + type: object + '400': + description: Bad request syntax or unsupported method + content: + application/json: + schema: + properties: + status_code: + type: integer + detail: + type: string + extra: + additionalProperties: {} + type: + - 'null' + - object + - array + type: object + required: + - detail + - status_code + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} deprecated: false - operationId: AnnotatorAnnotationAnnotatorAnnotation + /flatmap/{map_uuid}/pmtiles/{layer}: + get: + summary: FlatmapGetPmtiles + description: Retrieve a PMTiles archive or layer for a flatmap. + operationId: FlatmapMapUuidPmtilesLayerFlatmapGetPmtiles parameters: - - allowEmptyValue: false - allowReserved: false + - name: map_uuid + in: path + schema: + type: string + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap + listing endpoint. See [GET /](#get-/) for the list of available flatmaps. + examples: + - a5139708-c35a-5ba5-b8e8-a7ce6559224a + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap listing + endpoint. See [GET /](#get-/) for the list of available flatmaps. + required: true deprecated: false - in: query - name: id - required: false + examples: + map_uuid-example-1: + summary: Example UUID + value: a5139708-c35a-5ba5-b8e8-a7ce6559224a + - name: layer + in: path schema: - oneOf: - - type: string - - type: 'null' + type: string + description: The name of the tile layer. + default: index + examples: + - index + description: The name of the tile layer. + required: true + deprecated: false + examples: + layer-example-1: + value: index + responses: + '200': + description: File Download + headers: + content-length: + schema: + type: string + description: File size in bytes + required: false + deprecated: false + last-modified: + schema: + type: string + format: date-time + description: Last modified data-time in RFC 2822 format + required: false + deprecated: false + etag: + schema: + type: string + description: Entity tag + required: false + deprecated: false + content: + ? '' + : schema: + type: string + contentMediaType: application/octet-stream + '400': + description: Bad request syntax or unsupported method + content: + application/json: + schema: + properties: + status_code: + type: integer + detail: + type: string + extra: + additionalProperties: {} + type: + - 'null' + - object + - array + type: object + required: + - detail + - status_code + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} + deprecated: false + /flatmap/{map_uuid}/pmtiles: + get: + summary: FlatmapGetPmtiles + description: Retrieve a PMTiles archive or layer for a flatmap. + operationId: FlatmapMapUuidPmtilesFlatmapGetPmtiles + parameters: + - name: map_uuid + in: path + schema: + type: string + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap + listing endpoint. See [GET /](#get-/) for the list of available flatmaps. + examples: + - a5139708-c35a-5ba5-b8e8-a7ce6559224a + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap listing + endpoint. See [GET /](#get-/) for the list of available flatmaps. + required: true + deprecated: false + examples: + map_uuid-example-1: + summary: Example UUID + value: a5139708-c35a-5ba5-b8e8-a7ce6559224a responses: '200': + description: File Download + headers: + content-length: + schema: + type: string + description: File size in bytes + required: false + deprecated: false + last-modified: + schema: + type: string + format: date-time + description: Last modified data-time in RFC 2822 format + required: false + deprecated: false + etag: + schema: + type: string + description: Entity tag + required: false + deprecated: false + content: + ? '' + : schema: + type: string + contentMediaType: application/octet-stream + '400': + description: Bad request syntax or unsupported method content: application/json: schema: + properties: + status_code: + type: integer + detail: + type: string + extra: + additionalProperties: {} + type: + - 'null' + - object + - array type: object + required: + - detail + - status_code + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} + deprecated: false + /flatmap/{map_uuid}/images/{image}: + get: + summary: FlatmapImage + description: Retrieve an image file associated with the specified flatmap. + operationId: FlatmapMapUuidImagesFlatmapImage + parameters: + - name: map_uuid + in: path + schema: + type: string + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap + listing endpoint. See [GET /](#get-/) for the list of available flatmaps. + examples: + - a5139708-c35a-5ba5-b8e8-a7ce6559224a + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap listing + endpoint. See [GET /](#get-/) for the list of available flatmaps. + required: true + deprecated: false + examples: + map_uuid-example-1: + summary: Example UUID + value: a5139708-c35a-5ba5-b8e8-a7ce6559224a + - name: image + in: path + schema: + type: string + description: The image filename located in the flatmap images directory. + examples: + - human-flatmap_female.svg + description: The image filename located in the flatmap images directory. + required: true + deprecated: false + examples: + image-example-1: + value: human-flatmap_female.svg + responses: + '200': description: Request fulfilled, document follows headers: {} + content: + application/json: + schema: {} '400': + description: Bad request syntax or unsupported method content: application/json: schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 properties: + status_code: + type: integer detail: type: string extra: @@ -328,43 +682,106 @@ paths: - 'null' - object - array - status_code: - type: integer + type: object required: - detail - status_code - type: object - description: Bad request syntax or unsupported method - summary: AnnotatorAnnotation - post: + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} deprecated: false - operationId: AnnotatorAnnotationAnnotatorAddAnnotation - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/AnnotationUpdateRequest' + /flatmap/{map_uuid}/tiles/{layer}/{z}/{x}/{y}: + get: + summary: FlatmapImageTiles + description: Retrieve a raster tile for the specified flatmap layer and tile + coordinates. + operationId: FlatmapMapUuidTilesLayerZXYFlatmapImageTiles + parameters: + - name: map_uuid + in: path + schema: + type: string + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap + listing endpoint. See [GET /](#get-/) for the list of available flatmaps. + examples: + - a5139708-c35a-5ba5-b8e8-a7ce6559224a + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap listing + endpoint. See [GET /](#get-/) for the list of available flatmaps. + required: true + deprecated: false + examples: + map_uuid-example-1: + summary: Example UUID + value: a5139708-c35a-5ba5-b8e8-a7ce6559224a + - name: layer + in: path + schema: + type: string + description: The name of the tile layer. + examples: + - index + description: The name of the tile layer. + required: true + deprecated: false + examples: + layer-example-1: + value: index + - name: z + in: path + schema: + type: integer + description: Tile zoom level. + examples: + - 6 + description: Tile zoom level. + required: true + deprecated: false + examples: + z-example-1: + value: 6 + - name: y + in: path + schema: + type: integer + description: Tile X coordinate. + examples: + - 30 + description: Tile X coordinate. + required: true + deprecated: false + examples: + y-example-1: + value: 30 + - name: x + in: path + schema: + type: integer + description: Tile Y coordinate. + examples: + - 30 + description: Tile Y coordinate. required: true + deprecated: false + examples: + x-example-1: + value: 30 responses: - '201': + '200': + description: Request fulfilled, document follows + headers: {} content: application/json: - schema: - oneOf: - - type: object - - {} - description: Document created, URL follows - headers: {} + schema: {} '400': + description: Bad request syntax or unsupported method content: application/json: schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 properties: + status_code: + type: integer detail: type: string extra: @@ -373,47 +790,78 @@ paths: - 'null' - object - array - status_code: - type: integer + type: object required: - detail - status_code - type: object - description: Bad request syntax or unsupported method - summary: AnnotatorAddAnnotation - /annotator/annotation/: - get: + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} deprecated: false - operationId: AnnotatorAnnotationAnnotatorAnnotation + /flatmap/{map_uuid}: + get: + summary: FlatmapIndex + description: Return a flatmap. Use the Accept header to request RDF (text/turtle), + SVG, or JSON. + operationId: FlatmapMapUuidFlatmapIndex parameters: - - allowEmptyValue: false - allowReserved: false + - name: map_uuid + in: path + schema: + type: string + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap + listing endpoint. See [GET /](#get-/) for the list of available flatmaps. + examples: + - a5139708-c35a-5ba5-b8e8-a7ce6559224a + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap listing + endpoint. See [GET /](#get-/) for the list of available flatmaps. + required: true deprecated: false + examples: + map_uuid-example-1: + summary: Example UUID + value: a5139708-c35a-5ba5-b8e8-a7ce6559224a + - name: extras in: query - name: id - required: false schema: - oneOf: - - type: string - - type: 'null' + type: string + description: Optional extra entries to include in the returned index, separated + by `;`. Valid values are `mapAnnotations`, `mapLayers`, `mapMetadata`, + `mapPathways`, and `mapStyle`. + default: '' + examples: + - mapMetadata;mapStyle + description: Optional extra entries to include in the returned index, separated + by `;`. Valid values are `mapAnnotations`, `mapLayers`, `mapMetadata`, `mapPathways`, + and `mapStyle`. + required: false + deprecated: false + allowEmptyValue: false + allowReserved: false + examples: + extras-example-1: + summary: Multiple extras + value: mapMetadata;mapStyle responses: '200': + description: Request fulfilled, document follows + headers: {} content: application/json: schema: - type: object - description: Request fulfilled, document follows - headers: {} + oneOf: + - type: object + - {} '400': + description: Bad request syntax or unsupported method content: application/json: schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 properties: + status_code: + type: integer detail: type: string extra: @@ -422,128 +870,130 @@ paths: - 'null' - object - array - status_code: - type: integer + type: object required: - detail - status_code - type: object - description: Bad request syntax or unsupported method - summary: AnnotatorAnnotation - /annotator/annotations: - get: - deprecated: false - operationId: AnnotatorAnnotationsAnnotatorAnnotations - responses: - '200': - content: - application/json: - schema: - items: - type: object - type: array - description: Request fulfilled, document follows - headers: {} - summary: AnnotatorAnnotations - /annotator/authenticate: - get: + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} deprecated: false - operationId: AnnotatorAuthenticateAnnotatorAuthenticate - responses: - '200': - content: - application/json: - schema: - oneOf: - - type: object - - {} - description: Request fulfilled, document follows - headers: {} - summary: AnnotatorAuthenticate - /annotator/download: + /flatmap/{map_uuid}/layers: get: - deprecated: false - operationId: AnnotatorDownloadAnnotatorDownload + summary: FlatmapLayers + description: Retrieve layer definitions and metadata for a flatmap. + operationId: FlatmapMapUuidLayersFlatmapLayers + parameters: + - name: map_uuid + in: path + schema: + type: string + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap + listing endpoint. See [GET /](#get-/) for the list of available flatmaps. + examples: + - a5139708-c35a-5ba5-b8e8-a7ce6559224a + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap listing + endpoint. See [GET /](#get-/) for the list of available flatmaps. + required: true + deprecated: false + examples: + map_uuid-example-1: + summary: Example UUID + value: a5139708-c35a-5ba5-b8e8-a7ce6559224a responses: '200': - content: - application/json: - schema: - items: - type: object - type: array description: Request fulfilled, document follows headers: {} - summary: AnnotatorDownload - /annotator/features: - get: - deprecated: false - operationId: AnnotatorFeaturesAnnotatorFeatures - responses: - '200': content: application/json: schema: type: object - description: Request fulfilled, document follows - headers: {} - summary: AnnotatorFeatures - /annotator/items: - get: - deprecated: false - operationId: AnnotatorItemsAnnotatorAnnotatedItems - responses: - '200': + '400': + description: Bad request syntax or unsupported method content: application/json: schema: + properties: + status_code: + type: integer + detail: + type: string + extra: + additionalProperties: {} + type: + - 'null' + - object + - array type: object - description: Request fulfilled, document follows - headers: {} - summary: AnnotatorAnnotatedItems - /annotator/unauthenticate: - get: + required: + - detail + - status_code + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} deprecated: false - operationId: AnnotatorUnauthenticateAnnotatorUnauthenticate + /flatmap/{map_uuid}/log: + get: + summary: FlatmapMakerLog + description: Retrieve the flatmap maker log for the specified flatmap. + operationId: FlatmapMapUuidLogFlatmapMakerLog + parameters: + - name: map_uuid + in: path + schema: + type: string + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap + listing endpoint. See [GET /](#get-/) for the list of available flatmaps. + examples: + - a5139708-c35a-5ba5-b8e8-a7ce6559224a + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap listing + endpoint. See [GET /](#get-/) for the list of available flatmaps. + required: true + deprecated: false + examples: + map_uuid-example-1: + summary: Example UUID + value: a5139708-c35a-5ba5-b8e8-a7ce6559224a responses: '200': - content: - application/json: + description: File Download + headers: + content-length: schema: - type: object - description: Request fulfilled, document follows - headers: {} - summary: AnnotatorUnauthenticate - /annotator/update: - post: - deprecated: false - operationId: AnnotatorUpdateAnnotatorUpdateStatus - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/AnnotationUpdateRequest' - required: true - responses: - '201': - content: - application/json: + type: string + description: File size in bytes + required: false + deprecated: false + last-modified: schema: - oneOf: - - type: object - - {} - description: Document created, URL follows - headers: {} + type: string + format: date-time + description: Last modified data-time in RFC 2822 format + required: false + deprecated: false + etag: + schema: + type: string + description: Entity tag + required: false + deprecated: false + content: + ? '' + : schema: + type: string + contentMediaType: application/octet-stream '400': + description: Bad request syntax or unsupported method content: application/json: schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 properties: + status_code: + type: integer detail: type: string extra: @@ -552,58 +1002,68 @@ paths: - 'null' - object - array - status_code: - type: integer + type: object required: - detail - status_code - type: object - description: Bad request syntax or unsupported method - summary: AnnotatorUpdateStatus - /competency/queries: - get: + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} deprecated: false - operationId: CompetencyQueriesCompetencyQueryDefinitions + /: + get: + summary: FlatmapMaps + description: Retrieve a list of available flatmaps. + operationId: FlatmapMaps responses: '200': + description: Request fulfilled, document follows + headers: {} content: application/json: schema: - items: - $ref: '#/components/schemas/QueryDefinitionSummary' type: array - description: Request fulfilled, document follows - headers: {} - summary: CompetencyQueryDefinitions - /competency/queries/{query_id}: - get: deprecated: false - operationId: CompetencyQueriesQueryIdCompetencyQueryDefinition + /flatmap/{map_uuid}/metadata: + get: + summary: FlatmapMetadata + description: Retrieve descriptive metadata for the specified flatmap. + operationId: FlatmapMapUuidMetadataFlatmapMetadata parameters: - - deprecated: false + - name: map_uuid in: path - name: query_id - required: true schema: type: string + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap + listing endpoint. See [GET /](#get-/) for the list of available flatmaps. + examples: + - a5139708-c35a-5ba5-b8e8-a7ce6559224a + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap listing + endpoint. See [GET /](#get-/) for the list of available flatmaps. + required: true + deprecated: false + examples: + map_uuid-example-1: + summary: Example UUID + value: a5139708-c35a-5ba5-b8e8-a7ce6559224a responses: '200': + description: Request fulfilled, document follows + headers: {} content: application/json: schema: - $ref: '#/components/schemas/QueryDefinitionDict' - description: Request fulfilled, document follows - headers: {} + type: object '400': + description: Bad request syntax or unsupported method content: application/json: schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 properties: + status_code: + type: integer detail: type: string extra: @@ -612,44 +1072,54 @@ paths: - 'null' - object - array - status_code: - type: integer + type: object required: - detail - status_code - type: object - description: Bad request syntax or unsupported method - summary: CompetencyQueryDefinition - /competency/query: - post: + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} deprecated: false - operationId: CompetencyQueryCompetencyQuery - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/QueryRequest' + /flatmap/{map_uuid}/pathways: + get: + summary: FlatmapPathways + description: Retrieve pathway definitions and metadata for a flatmap. + operationId: FlatmapMapUuidPathwaysFlatmapPathways + parameters: + - name: map_uuid + in: path + schema: + type: string + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap + listing endpoint. See [GET /](#get-/) for the list of available flatmaps. + examples: + - a5139708-c35a-5ba5-b8e8-a7ce6559224a + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap listing + endpoint. See [GET /](#get-/) for the list of available flatmaps. required: true + deprecated: false + examples: + map_uuid-example-1: + summary: Example UUID + value: a5139708-c35a-5ba5-b8e8-a7ce6559224a responses: - '201': + '200': + description: Request fulfilled, document follows + headers: {} content: application/json: schema: - oneOf: - - $ref: '#/components/schemas/QueryResults' - - $ref: '#/components/schemas/QueryError' - description: Document created, URL follows - headers: {} + type: object '400': + description: Bad request syntax or unsupported method content: application/json: schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 properties: + status_code: + type: integer detail: type: string extra: @@ -658,45 +1128,68 @@ paths: - 'null' - object - array - status_code: - type: integer + type: object required: - detail - status_code - type: object - description: Bad request syntax or unsupported method - summary: CompetencyQuery - /flatmap/{map_uuid}: - get: + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} deprecated: false - operationId: FlatmapMapUuidFlatmapIndex + /flatmap/{map_uuid}/connectivity/{path_id}: + get: + summary: FlatmapConnectivity + description: Retrieve connectivity and anatomical features for a neuron population + pathway. + operationId: FlatmapMapUuidConnectivityPathIdFlatmapConnectivity parameters: - - deprecated: false + - name: map_uuid in: path - name: map_uuid + schema: + type: string + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap + listing endpoint. See [GET /](#get-/) for the list of available flatmaps. + examples: + - a5139708-c35a-5ba5-b8e8-a7ce6559224a + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap listing + endpoint. See [GET /](#get-/) for the list of available flatmaps. required: true + deprecated: false + examples: + map_uuid-example-1: + summary: Example UUID + value: a5139708-c35a-5ba5-b8e8-a7ce6559224a + - name: path_id + in: path schema: type: string + description: The ID of a neuron population pathway. + examples: + - ilxtr:neuron-type-aacar-10a + description: The ID of a neuron population pathway. + required: true + deprecated: false + examples: + path_id-example-1: + value: ilxtr:neuron-type-aacar-10a responses: '200': + description: Request fulfilled, document follows + headers: {} content: application/json: schema: - oneOf: - - type: object - - {} - description: Request fulfilled, document follows - headers: {} + type: object '400': + description: Bad request syntax or unsupported method content: application/json: schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 properties: + status_code: + type: integer detail: type: string extra: @@ -705,43 +1198,74 @@ paths: - 'null' - object - array - status_code: - type: integer + type: object required: - detail - status_code - type: object - description: Bad request syntax or unsupported method - summary: FlatmapIndex - /flatmap/{map_uuid}/annotations: - get: + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} deprecated: false - operationId: FlatmapMapUuidAnnotationsFlatmapAnnotation + /flatmap/{map_uuid}/style: + get: + summary: FlatmapStyle + description: Retrieve the map styling configuration for a flatmap. + operationId: FlatmapMapUuidStyleFlatmapStyle parameters: - - deprecated: false + - name: map_uuid in: path - name: map_uuid - required: true schema: type: string + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap + listing endpoint. See [GET /](#get-/) for the list of available flatmaps. + examples: + - a5139708-c35a-5ba5-b8e8-a7ce6559224a + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap listing + endpoint. See [GET /](#get-/) for the list of available flatmaps. + required: true + deprecated: false + examples: + map_uuid-example-1: + summary: Example UUID + value: a5139708-c35a-5ba5-b8e8-a7ce6559224a responses: '200': - content: - application/json: + description: File Download + headers: + content-length: schema: - type: object - description: Request fulfilled, document follows - headers: {} + type: string + description: File size in bytes + required: false + deprecated: false + last-modified: + schema: + type: string + format: date-time + description: Last modified data-time in RFC 2822 format + required: false + deprecated: false + etag: + schema: + type: string + description: Entity tag + required: false + deprecated: false + content: + ? '' + : schema: + type: string + contentMediaType: application/octet-stream '400': + description: Bad request syntax or unsupported method content: application/json: schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 properties: + status_code: + type: integer detail: type: string extra: @@ -750,49 +1274,55 @@ paths: - 'null' - object - array - status_code: - type: integer + type: object required: - detail - status_code - type: object - description: Bad request syntax or unsupported method - summary: FlatmapAnnotation - /flatmap/{map_uuid}/connectivity/{path_id}: - get: + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} deprecated: false - operationId: FlatmapMapUuidConnectivityPathIdFlatmapConnectivity + /flatmap/{map_uuid}/termgraph: + get: + summary: FlatmapTermgraph + description: Retrieve the anatomical term hierarchy for structures represented + in the specified flatmap. + operationId: FlatmapMapUuidTermgraphFlatmapTermgraph parameters: - - deprecated: false + - name: map_uuid in: path - name: map_uuid - required: true schema: type: string - - deprecated: false - in: path - name: path_id + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap + listing endpoint. See [GET /](#get-/) for the list of available flatmaps. + examples: + - a5139708-c35a-5ba5-b8e8-a7ce6559224a + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap listing + endpoint. See [GET /](#get-/) for the list of available flatmaps. required: true - schema: - type: string + deprecated: false + examples: + map_uuid-example-1: + summary: Example UUID + value: a5139708-c35a-5ba5-b8e8-a7ce6559224a responses: '200': + description: Request fulfilled, document follows + headers: {} content: application/json: schema: type: object - description: Request fulfilled, document follows - headers: {} '400': + description: Bad request syntax or unsupported method content: application/json: schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 properties: + status_code: + type: integer detail: type: string extra: @@ -801,48 +1331,92 @@ paths: - 'null' - object - array - status_code: - type: integer + type: object required: - detail - status_code - type: object - description: Bad request syntax or unsupported method - summary: FlatmapConnectivity - /flatmap/{map_uuid}/images/{image}: - get: + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} deprecated: false - operationId: FlatmapMapUuidImagesFlatmapImage + /flatmap/{map_uuid}/mvtiles/{z}/{x}/{y}: + get: + summary: FlatmapVectorTiles + description: Retrieve a vector map tile for the specified flatmap and tile coordinates. + operationId: FlatmapMapUuidMvtilesZXYFlatmapVectorTiles parameters: - - deprecated: false + - name: map_uuid + in: path + schema: + type: string + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap + listing endpoint. See [GET /](#get-/) for the list of available flatmaps. + examples: + - a5139708-c35a-5ba5-b8e8-a7ce6559224a + description: The UUID of a flatmap. Obtain valid UUIDs from the flatmap listing + endpoint. See [GET /](#get-/) for the list of available flatmaps. + required: true + deprecated: false + examples: + map_uuid-example-1: + summary: Example UUID + value: a5139708-c35a-5ba5-b8e8-a7ce6559224a + - name: z + in: path + schema: + type: integer + description: Tile zoom level. + examples: + - 6 + description: Tile zoom level. + required: true + deprecated: false + examples: + z-example-1: + value: 6 + - name: y + in: path + schema: + type: integer + description: Tile Y coordinate. + examples: + - 30 + description: Tile Y coordinate. + required: true + deprecated: false + examples: + y-example-1: + value: 30 + - name: x in: path - name: map_uuid - required: true schema: - type: string - - deprecated: false - in: path - name: image + type: integer + description: Tile X coordinate. + examples: + - 30 + description: Tile X coordinate. required: true - schema: - type: string + deprecated: false + examples: + x-example-1: + value: 30 responses: '200': + description: Request fulfilled, document follows + headers: {} content: application/json: schema: {} - description: Request fulfilled, document follows - headers: {} '400': + description: Bad request syntax or unsupported method content: application/json: schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 properties: + status_code: + type: integer detail: type: string extra: @@ -851,43 +1425,45 @@ paths: - 'null' - object - array - status_code: - type: integer + type: object required: - detail - status_code - type: object - description: Bad request syntax or unsupported method - summary: FlatmapImage - /flatmap/{map_uuid}/layers: - get: + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} deprecated: false - operationId: FlatmapMapUuidLayersFlatmapLayers - parameters: - - deprecated: false - in: path - name: map_uuid + /knowledge/query: + post: + summary: KnowledgeQuery + description: Execute a read-only SQL query against the flatmap knowledge store. + Use [GET /knowledge/schema](#get-/knowledge/schema) to inspect the available + tables and columns. + operationId: KnowledgeQueryKnowledgeQuery + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/QueryData' required: true - schema: - type: string responses: - '200': + '201': + description: Document created, URL follows + headers: {} content: application/json: schema: type: object - description: Request fulfilled, document follows - headers: {} '400': + description: Bad request syntax or unsupported method content: application/json: schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 properties: + status_code: + type: integer detail: type: string extra: @@ -896,108 +1472,123 @@ paths: - 'null' - object - array - status_code: - type: integer + type: object required: - detail - status_code - type: object - description: Bad request syntax or unsupported method - summary: FlatmapLayers - /flatmap/{map_uuid}/log: + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} + deprecated: false + /knowledge/schema: get: + summary: KnowledgeSchema + description: Return all knowledge-store tables, columns, and foreign-key relationships. + operationId: KnowledgeSchemaKnowledgeSchema + responses: + '200': + description: Request fulfilled, document follows + headers: {} + content: + application/json: + schema: + $ref: '#/components/schemas/DatabaseSchemaResponse' deprecated: false - operationId: FlatmapMapUuidLogFlatmapMakerLog - parameters: - - deprecated: false - in: path - name: map_uuid - required: true - schema: - type: string + /knowledge/schema-version: + get: + summary: KnowledgeSchemaVersion + description: Return the schema version of the flatmap knowledge store. + operationId: KnowledgeSchemaVersionKnowledgeSchemaVersion responses: '200': + description: Request fulfilled, document follows + headers: {} content: - ? '' - : schema: - contentMediaType: application/octet-stream - type: string + application/json: + schema: + type: object + deprecated: false + /knowledge/sources: + get: + summary: KnowledgeSources + description: List the available SCKAN knowledge-source versions, newest first. + operationId: KnowledgeSourcesKnowledgeSources + responses: + '200': + description: Request fulfilled, document follows + headers: {} + content: + application/json: + schema: + $ref: '#/components/schemas/KnowledgeSourcesResponse' + deprecated: false + /knowledge/sparcterms: + get: + summary: KnowledgeSparcterms + description: Download the cached SPARC anatomical hierarchy as JSON. + operationId: KnowledgeSparctermsKnowledgeSparcterms + responses: + '200': description: File Download headers: content-length: - deprecated: false - description: File size in bytes - required: false schema: type: string - etag: - deprecated: false - description: Entity tag + description: File size in bytes required: false + deprecated: false + last-modified: schema: type: string - last-modified: - deprecated: false + format: date-time description: Last modified data-time in RFC 2822 format required: false + deprecated: false + etag: schema: - format: date-time type: string - '400': + description: Entity tag + required: false + deprecated: false content: - application/json: - schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 - properties: - detail: - type: string - extra: - additionalProperties: {} - type: - - 'null' - - object - - array - status_code: - type: integer - required: - - detail - - status_code - type: object - description: Bad request syntax or unsupported method - summary: FlatmapMakerLog - /flatmap/{map_uuid}/metadata: - get: + ? '' + : schema: + type: string + contentMediaType: application/octet-stream deprecated: false - operationId: FlatmapMapUuidMetadataFlatmapMetadata - parameters: - - deprecated: false - in: path - name: map_uuid + /make/map: + post: + summary: MakeMap + description: 'Start a flatmap generation process. Requires `Authorization: Bearer + TOKEN`. See the [flatmap-server README](https://github.com/AnatomicMaps/flatmap-server#authentication) + for authentication details.' + operationId: MakeMapMakeMap + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/MakerData' required: true - schema: - type: string responses: - '200': + '201': + description: Document created, URL follows + headers: {} content: application/json: schema: - type: object - description: Request fulfilled, document follows - headers: {} + oneOf: + - $ref: '#/components/schemas/MakerResponse' + - {} '400': + description: Bad request syntax or unsupported method content: application/json: schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 properties: + status_code: + type: integer detail: type: string extra: @@ -1006,60 +1597,54 @@ paths: - 'null' - object - array - status_code: - type: integer + type: object required: - detail - status_code - type: object - description: Bad request syntax or unsupported method - summary: FlatmapMetadata - /flatmap/{map_uuid}/mvtiles/{z}/{x}/{y}: - get: + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} deprecated: false - operationId: FlatmapMapUuidMvtilesZXYFlatmapVectorTiles + /make/process-log/{pid}: + get: + summary: MakeProcessLog + description: 'Retrieve the log for a map-generation process. Requires `Authorization: + Bearer TOKEN`.' + operationId: MakeProcessLogPidMakeProcessLog parameters: - - deprecated: false - in: path - name: map_uuid - required: true - schema: - type: string - - deprecated: false + - name: pid in: path - name: z - required: true - schema: - type: integer - - deprecated: false - in: path - name: y - required: true schema: type: integer - - deprecated: false - in: path - name: x + description: The operating-system process ID of the map-generation process. + examples: + - 12345 + description: The operating-system process ID of the map-generation process. required: true - schema: - type: integer + deprecated: false + examples: + pid-example-1: + value: 12345 responses: '200': - content: - application/json: - schema: {} description: Request fulfilled, document follows headers: {} + content: + application/json: + schema: + oneOf: + - type: object + - {} '400': + description: Bad request syntax or unsupported method content: application/json: schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 properties: + status_code: + type: integer detail: type: string extra: @@ -1068,43 +1653,54 @@ paths: - 'null' - object - array - status_code: - type: integer + type: object required: - detail - status_code - type: object - description: Bad request syntax or unsupported method - summary: FlatmapVectorTiles - /flatmap/{map_uuid}/pathways: - get: + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} deprecated: false - operationId: FlatmapMapUuidPathwaysFlatmapPathways + /make/status/{id}: + get: + summary: MakeStatus + description: 'Retrieve the status of a map-generation process. Requires `Authorization: + Bearer TOKEN`.' + operationId: MakeStatusIdMakeStatus parameters: - - deprecated: false + - name: id in: path - name: map_uuid - required: true schema: type: string + description: The server-assigned ID of the map-generation process. + examples: + - f4a76fe4-8fd1-4f19-839b-6e08ca0cee30 + description: The server-assigned ID of the map-generation process. + required: true + deprecated: false + examples: + id-example-1: + value: f4a76fe4-8fd1-4f19-839b-6e08ca0cee30 responses: '200': - content: - application/json: - schema: - type: object description: Request fulfilled, document follows headers: {} + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/MakerStatus' + - {} '400': + description: Bad request syntax or unsupported method content: application/json: schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 properties: + status_code: + type: integer detail: type: string extra: @@ -1113,63 +1709,54 @@ paths: - 'null' - object - array - status_code: - type: integer + type: object required: - detail - status_code - type: object - description: Bad request syntax or unsupported method - summary: FlatmapPathways - /flatmap/{map_uuid}/style: - get: + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} deprecated: false - operationId: FlatmapMapUuidStyleFlatmapStyle + /make/log/{id}: + get: + summary: MakeStatusLog + description: 'Retrieve the process status and unseen log records. Requires `Authorization: + Bearer TOKEN`.' + operationId: MakeLogIdMakeStatusLog parameters: - - deprecated: false + - name: id in: path - name: map_uuid - required: true schema: type: string + description: The server-assigned ID of the map-generation process. + examples: + - f4a76fe4-8fd1-4f19-839b-6e08ca0cee30 + description: The server-assigned ID of the map-generation process. + required: true + deprecated: false + examples: + id-example-1: + value: f4a76fe4-8fd1-4f19-839b-6e08ca0cee30 responses: '200': + description: Request fulfilled, document follows + headers: {} content: - ? '' - : schema: - contentMediaType: application/octet-stream - type: string - description: File Download - headers: - content-length: - deprecated: false - description: File size in bytes - required: false - schema: - type: string - etag: - deprecated: false - description: Entity tag - required: false - schema: - type: string - last-modified: - deprecated: false - description: Last modified data-time in RFC 2822 format - required: false + application/json: schema: - format: date-time - type: string + oneOf: + - $ref: '#/components/schemas/MakerLogResponse' + - {} '400': + description: Bad request syntax or unsupported method content: application/json: schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 properties: + status_code: + type: integer detail: type: string extra: @@ -1178,431 +1765,391 @@ paths: - 'null' - object - array - status_code: - type: integer + type: object required: - detail - status_code - type: object - description: Bad request syntax or unsupported method - summary: FlatmapStyle - /flatmap/{map_uuid}/termgraph: + description: Validation Exception + examples: + - status_code: 400 + detail: Bad Request + extra: {} + deprecated: false + /version: get: + summary: Version + description: Returns the flatmap server version. + operationId: VersionVersion + responses: + '200': + description: Request fulfilled, document follows + headers: {} + content: + application/json: + schema: + items: + type: object + type: array deprecated: false - operationId: FlatmapMapUuidTermgraphFlatmapTermgraph - parameters: - - deprecated: false - in: path - name: map_uuid - required: true - schema: +components: + schemas: + AnnotationUpdateRequest: + properties: + key: + type: string + session: + type: string + data: + type: object + type: object + required: + - data + - key + - session + title: AnnotationUpdateRequest + description: The authenticated session (`key`, `session`) and annotation data + to create or update. + ColumnDefinition: + properties: + name: + type: string + type: + type: string + primary_key: + type: boolean + nullable: + type: boolean + type: object + required: + - name + - nullable + - primary_key + - type + title: ColumnDefinition + DatabaseSchemaResponse: + properties: + tables: + items: + $ref: '#/components/schemas/TableDefinition' + type: array + type: object + required: + - tables + title: DatabaseSchemaResponse + ForeignKeyDefinition: + properties: + column: + type: string + to_table: + type: string + to_column: + type: string + type: object + required: + - column + - to_column + - to_table + title: ForeignKeyDefinition + KnowledgeSourcesResponse: + properties: + sources: + items: + type: string + type: array + type: object + required: + - sources + title: KnowledgeSourcesResponse + MakerData: + properties: + source: + type: string + manifest: + type: string + commit: + oneOf: + - type: string + - type: 'null' + force: + oneOf: + - type: boolean + - type: 'null' + type: object + required: + - manifest + - source + title: MakerData + description: The manifest source and options for generating a flatmap. + example: + source: https://github.com/AnatomicMaps/human-flatmap + manifest: female.manifest.json + commit: main + force: false + MakerLogResponse: + properties: + status: + type: string + id: + oneOf: + - type: integer + - type: 'null' + pid: + oneOf: + - type: integer + - type: 'null' + log: + type: string + stamp: + oneOf: + - type: string + - type: 'null' + type: object + required: + - id + - log + - pid + - status + title: MakerLogResponse + MakerResponse: + properties: + status: + type: string + id: + oneOf: + - type: integer + - type: 'null' + pid: + oneOf: + - type: integer + - type: 'null' + source: + type: string + commit: + oneOf: + - type: string + - type: 'null' + type: object + required: + - id + - pid + - source + - status + title: MakerResponse + MakerStatus: + properties: + status: + type: string + id: + oneOf: + - type: integer + - type: 'null' + pid: + oneOf: + - type: integer + - type: 'null' + type: object + required: + - id + - pid + - status + title: MakerStatus + ParameterChoiceDict: + properties: + label: + type: string + value: + type: string + type: object + required: + - label + - value + title: ParameterChoiceDict + ParameterDefinitionDict: + properties: + column: + type: string + label: + type: string + type: + type: string + choices: + items: + $ref: '#/components/schemas/ParameterChoiceDict' + type: array + multiple: + type: boolean + default: + type: string + type: object + required: + - column + - label + title: ParameterDefinitionDict + QueryData: + properties: + sql: type: string - responses: - '200': - content: - application/json: - schema: - type: object - description: Request fulfilled, document follows - headers: {} - '400': - content: - application/json: - schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 - properties: - detail: - type: string - extra: - additionalProperties: {} - type: - - 'null' - - object - - array - status_code: - type: integer - required: - - detail - - status_code - type: object - description: Bad request syntax or unsupported method - summary: FlatmapTermgraph - /flatmap/{map_uuid}/tiles/{layer}/{z}/{x}/{y}: - get: - deprecated: false - operationId: FlatmapMapUuidTilesLayerZXYFlatmapImageTiles - parameters: - - deprecated: false - in: path - name: map_uuid - required: true - schema: + description: A read-only SQLite SQL statement to execute against the knowledge + store. + params: + oneOf: + - items: + type: string + type: array + - type: 'null' + description: Values bound to positional `?` placeholders in `sql`, in order. + type: object + required: + - sql + title: QueryData + description: SQL statement and positional parameter values for a knowledge-store + query. + example: + sql: SELECT value FROM metadata WHERE name = ? + params: + - schema_version + QueryDefinitionDict: + properties: + id: type: string - - deprecated: false - in: path - name: layer - required: true - schema: + label: type: string - - deprecated: false - in: path - name: z - required: true - schema: - type: integer - - deprecated: false - in: path - name: y - required: true - schema: - type: integer - - deprecated: false - in: path - name: x - required: true - schema: - type: integer - responses: - '200': - content: - application/json: - schema: {} - description: Request fulfilled, document follows - headers: {} - '400': - content: - application/json: - schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 - properties: - detail: - type: string - extra: - additionalProperties: {} - type: - - 'null' - - object - - array - status_code: - type: integer - required: - - detail - - status_code - type: object - description: Bad request syntax or unsupported method - summary: FlatmapImageTiles - /knowledge/query: - post: - deprecated: false - operationId: KnowledgeQueryKnowledgeQuery - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/QueryData' - required: true - responses: - '201': - content: - application/json: - schema: - type: object - description: Document created, URL follows - headers: {} - '400': - content: - application/json: - schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 - properties: - detail: - type: string - extra: - additionalProperties: {} - type: - - 'null' - - object - - array - status_code: - type: integer - required: - - detail - - status_code - type: object - description: Bad request syntax or unsupported method - summary: KnowledgeQuery - /knowledge/schema-version: - get: - deprecated: false - operationId: KnowledgeSchemaVersionKnowledgeSchemaVersion - responses: - '200': - content: - application/json: - schema: - type: object - description: Request fulfilled, document follows - headers: {} - summary: KnowledgeSchemaVersion - /knowledge/sources: - get: - deprecated: false - operationId: KnowledgeSourcesKnowledgeSources - responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/KnowledgeSourcesResponse' - description: Request fulfilled, document follows - headers: {} - summary: KnowledgeSources - /knowledge/sparcterms: - get: - deprecated: false - operationId: KnowledgeSparctermsKnowledgeSparcterms - responses: - '200': - content: - ? '' - : schema: - contentMediaType: application/octet-stream - type: string - description: File Download - headers: - content-length: - deprecated: false - description: File size in bytes - required: false - schema: - type: string - etag: - deprecated: false - description: Entity tag - required: false - schema: - type: string - last-modified: - deprecated: false - description: Last modified data-time in RFC 2822 format - required: false - schema: - format: date-time - type: string - summary: KnowledgeSparcterms - /make/log/{id}: - get: - deprecated: false - operationId: MakeLogIdMakeStatusLog - parameters: - - deprecated: false - in: path - name: id - required: true - schema: + description: + type: string + parameters: + items: + $ref: '#/components/schemas/ParameterDefinitionDict' + type: array + results: + items: + $ref: '#/components/schemas/ResultDefinitionDict' + type: array + type: object + required: + - id + - label + - results + title: QueryDefinitionDict + QueryDefinitionSummary: + properties: + id: + type: string + label: + type: string + description: + type: string + type: object + required: + - id + - label + title: QueryDefinitionSummary + QueryError: + properties: + error: + type: string + type: object + required: + - error + title: QueryError + QueryParameter: + properties: + column: + type: string + value: + oneOf: + - type: string + - items: + type: string + type: array + negate: + type: boolean + type: object + required: + - column + - value + title: QueryParameter + QueryRequest: + properties: + query_id: type: string - responses: - '200': - content: - application/json: - schema: - oneOf: - - $ref: '#/components/schemas/MakerLogResponse' - - {} - description: Request fulfilled, document follows - headers: {} - '400': - content: - application/json: - schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 - properties: - detail: - type: string - extra: - additionalProperties: {} - type: - - 'null' - - object - - array - status_code: - type: integer - required: - - detail - - status_code - type: object - description: Bad request syntax or unsupported method - summary: MakeStatusLog - /make/map: - post: - deprecated: false - operationId: MakeMapMakeMap - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/MakerData' - required: true - responses: - '201': - content: - application/json: - schema: - oneOf: - - $ref: '#/components/schemas/MakerResponse' - - {} - description: Document created, URL follows - headers: {} - '400': - content: - application/json: - schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 - properties: - detail: - type: string - extra: - additionalProperties: {} - type: - - 'null' - - object - - array - status_code: - type: integer - required: - - detail - - status_code - type: object - description: Bad request syntax or unsupported method - summary: MakeMap - /make/process-log/{pid}: - get: - deprecated: false - operationId: MakeProcessLogPidMakeProcessLog - parameters: - - deprecated: false - in: path - name: pid - required: true - schema: + parameters: + items: + $ref: '#/components/schemas/QueryParameter' + type: array + order: + items: + type: string + type: array + limit: type: integer - responses: - '200': - content: - application/json: - schema: - oneOf: - - type: object - - {} - description: Request fulfilled, document follows - headers: {} - '400': - content: - application/json: - schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 - properties: - detail: - type: string - extra: - additionalProperties: {} - type: - - 'null' - - object - - array - status_code: - type: integer - required: - - detail - - status_code - type: object - description: Bad request syntax or unsupported method - summary: MakeProcessLog - /make/status/{id}: - get: - deprecated: false - operationId: MakeStatusIdMakeStatus - parameters: - - deprecated: false - in: path - name: id - required: true - schema: + type: object + required: + - query_id + title: QueryRequest + description: The competency query ID and the parameter values required by that + query. + example: + query_id: '1' + parameters: + - column: feature_id + value: UBERON:0001759 + - column: source_id + value: sckan-2026-02-11 + QueryResultRows: + properties: + keys: + items: + type: string + type: array + values: + items: + items: + type: string + type: array + type: array + type: object + required: + - keys + - values + title: QueryResultRows + QueryResults: + properties: + query_id: type: string - responses: - '200': - content: - application/json: - schema: - oneOf: - - $ref: '#/components/schemas/MakerStatus' - - {} - description: Request fulfilled, document follows - headers: {} - '400': - content: - application/json: - schema: - description: Validation Exception - examples: - - detail: Bad Request - extra: {} - status_code: 400 - properties: - detail: - type: string - extra: - additionalProperties: {} - type: - - 'null' - - object - - array - status_code: - type: integer - required: - - detail - - status_code - type: object - description: Bad request syntax or unsupported method - summary: MakeStatus - /version: - get: - deprecated: false - operationId: VersionVersion - responses: - '200': - content: - application/json: - schema: - items: - type: object - type: array - description: Request fulfilled, document follows - headers: {} - summary: Version -servers: -- url: '' + results: + $ref: '#/components/schemas/QueryResultRows' + type: object + required: + - query_id + - results + title: QueryResults + ResultDefinitionDict: + properties: + key: + type: string + label: + type: string + type: + type: string + type: object + required: + - key + title: ResultDefinitionDict + TableDefinition: + properties: + name: + type: string + columns: + items: + $ref: '#/components/schemas/ColumnDefinition' + type: array + foreign_keys: + items: + $ref: '#/components/schemas/ForeignKeyDefinition' + type: array + type: object + required: + - columns + - foreign_keys + - name + title: TableDefinition diff --git a/mapserver/server/__init__.py b/mapserver/server/__init__.py index 0e10b98..7ca85ef 100644 --- a/mapserver/server/__init__.py +++ b/mapserver/server/__init__.py @@ -104,7 +104,10 @@ def terminate(app: Litestar): #=============================================================================== -@get('/version') +@get( + '/version', + description='Returns the flatmap server version.' +) async def version() -> list[dict]: versions = [ {'id': 'server', 'version': __version__}, diff --git a/mapserver/server/annotator.py b/mapserver/server/annotator.py index 93983e1..989e1f1 100644 --- a/mapserver/server/annotator.py +++ b/mapserver/server/annotator.py @@ -24,13 +24,14 @@ import json import pathlib import sqlite3 -from typing import Any, Optional +from typing import Annotated, Any, Optional import uuid #=============================================================================== from litestar import exceptions, get, post, Request, Response, Router from litestar.middleware.session.server_side import ServerSideSessionConfig +from litestar.params import Body, Parameter #=============================================================================== @@ -103,7 +104,7 @@ SCHEMA_VERSION = '1.1' -ANNOTATION_STORE_SCHEMA = """ +ANNOTATION_STORE_SCHEMA = f""" begin; create table metadata (name text primary key, value text); create table annotations (id text primary key, resource text, itemid text, item text, created text, orcid text, creator text, annotation text, status text); @@ -371,7 +372,13 @@ def __authenticated_bearer(request: Request) -> bool: #=============================================================================== -@get('authenticate') +@get( + 'authenticate', + description=( + 'Authenticate a Pennsieve API key and create an annotator session. ' + 'Pass `key` as a query parameter; use the returned `session` with subsequent annotator requests.' + ), +) async def annotator_authenticate(query: dict[str, Any]) -> dict|Response: if (key := query.get('key')) is not None: user_data = get_pennsieve_user(key) # type: ignore @@ -389,7 +396,10 @@ async def annotator_authenticate(query: dict[str, Any]) -> dict|Response: #=============================================================================== -@get('unauthenticate') +@get( + 'unauthenticate', + description='Delete an annotator session. Pass its `session` value as a query parameter.', +) async def annotator_unauthenticate(query: dict[str, Any], request: Request) -> dict: if (session := query.get('session')) is not None: __del_session(session) @@ -398,7 +408,13 @@ async def annotator_unauthenticate(query: dict[str, Any], request: Request) -> d #=============================================================================== -@get('items/') +@get( + 'items/', + description=( + 'Retrieve annotated item IDs for a resource. Requires `key` and `session` query parameters ' + 'from [GET /annotator/authenticate](#get-/annotator/authenticate).' + ), +) async def annotator_annotated_items(query: dict[str, Any], request: Request) -> dict: if __authenticated_session(query, request): if (resource_id := __get_json_parameter(query, 'resource')) is not None: @@ -416,7 +432,13 @@ async def annotator_annotated_items(query: dict[str, Any], request: Request) -> #=============================================================================== -@get('features/') +@get( + 'features/', + description=( + 'Retrieve annotation features for a resource. Requires `key` and `session` query parameters ' + 'from [GET /annotator/authenticate](#get-/annotator/authenticate).' + ), +) async def annotator_features(query: dict[str, Any], request: Request) -> dict: if __authenticated_session(query, request): if (resource_id := __get_json_parameter(query, 'resource')) is not None: @@ -434,7 +456,13 @@ async def annotator_features(query: dict[str, Any], request: Request) -> dict: #=============================================================================== -@get('annotations/') +@get( + 'annotations/', + description=( + 'Retrieve annotations for a resource item. Requires `key` and `session` query parameters ' + 'from [GET /annotator/authenticate](#get-/annotator/authenticate).' + ), +) async def annotator_annotations(query: dict[str, Any], request: Request) -> list[dict]: if __authenticated_session(query, request): if ((resource_id := __get_json_parameter(query, 'resource')) is not None @@ -448,10 +476,37 @@ async def annotator_annotations(query: dict[str, Any], request: Request) -> list #=============================================================================== -@get(['annotation/', 'annotation/']) -async def annotator_annotation(query: dict[str, Any], request: Request, id: Optional[str]=None) -> dict: +AnnotationIdParameter = Annotated[ + str, + Parameter(description='The annotation ID to retrieve.'), +] + +@get( + 'annotation/{id:str}', + description=( + 'Retrieve an annotation by ID. Requires `key` and `session` query parameters ' + 'from [GET /annotator/authenticate](#get-/annotator/authenticate).' + ), +) +async def annotator_annotation_by_id(id: AnnotationIdParameter, query: dict[str, Any], request: Request) -> dict: if __authenticated_session(query, request): - annotation_id = __get_json_parameter(query, 'annotation', '') if id is None else id + annotation_store = AnnotationStore() + annotation = annotation_store.annotation(id) + annotation_store.close() + return annotation + raise exceptions.NotAuthorizedException() + +@get( + 'annotation/', + description=( + 'Retrieve an annotation by ID, passed as the `annotation` query parameter. ' + 'Requires `key` and `session` query parameters ' + 'from [GET /annotator/authenticate](#get-/annotator/authenticate).' + ), +) +async def annotator_annotation(query: dict[str, Any], request: Request) -> dict: + if __authenticated_session(query, request): + annotation_id = __get_json_parameter(query, 'annotation', '') annotation_store = AnnotationStore() annotation = annotation_store.annotation(annotation_id) annotation_store.close() @@ -468,8 +523,19 @@ class AnnotationUpdateRequest: #=============================================================================== -@post('annotation/') -async def annotator_add_annotation(data: AnnotationUpdateRequest, request: Request) -> dict|Response: +AnnotationUpdateBody = Annotated[ + AnnotationUpdateRequest, + Body(description='The authenticated session (`key`, `session`) and annotation data to create or update.'), +] + +@post( + 'annotation/', + description=( + 'Create an annotation. Requires `key` and `session` obtained from ' + '[GET /annotator/authenticate](#get-/annotator/authenticate), and an authenticated user with update permission.' + ), +) +async def annotator_add_annotation(data: AnnotationUpdateBody, request: Request) -> dict|Response: if __authenticated_session(dataclasses.asdict(data), request): if request.session['update']: annotation_store = AnnotationStore() @@ -482,8 +548,14 @@ async def annotator_add_annotation(data: AnnotationUpdateRequest, request: Reque #=============================================================================== -@post('update/') -async def annotator_update_status(data: AnnotationUpdateRequest, request: Request) -> dict|Response: +@post( + 'update/', + description=( + 'Update an annotation status. Requires `key` and `session` obtained from ' + '[GET /annotator/authenticate](#get-/annotator/authenticate), and an authenticated user with update permission.' + ), +) +async def annotator_update_status(data: AnnotationUpdateBody, request: Request) -> dict|Response: if __authenticated_session(dataclasses.asdict(data), request) or __authenticated_bearer(request): if request.session['update']: annotation_store = AnnotationStore() @@ -501,7 +573,10 @@ async def annotator_update_status(data: AnnotationUpdateRequest, request: Reques #=============================================================================== -@get('download/') +@get( + 'download/', + description='Download all annotations. Requires `Authorization: Bearer TOKEN`.', +) async def annotator_download(request: Request) -> list[dict]: if __authenticated_bearer(request): annotation_store = AnnotationStore() @@ -519,6 +594,7 @@ async def annotator_download(request: Request) -> list[dict]: annotator_add_annotation, annotator_annotated_items, annotator_annotation, + annotator_annotation_by_id, annotator_annotations, annotator_authenticate, annotator_download, @@ -540,7 +616,7 @@ async def annotator_download(request: Request) -> list[dict]: schema_version: Optional[str] = None row = store.db.execute("select name from sqlite_schema where type='table' and name='metadata'").fetchone() if row is not None: - row = store.db.execute("select value from metadata where name='schema_version").fetchone() + row = store.db.execute("select value from metadata where name='schema_version'").fetchone() if row is not None: schema_version = row[0] if schema_version != SCHEMA_VERSION: diff --git a/mapserver/server/competency.py b/mapserver/server/competency.py index 6219145..b89f70b 100644 --- a/mapserver/server/competency.py +++ b/mapserver/server/competency.py @@ -25,6 +25,9 @@ #=============================================================================== from litestar import get, post, Request, Router +from litestar.openapi.spec import Example +from litestar.params import Parameter, Body +from typing import Annotated #=============================================================================== @@ -35,25 +38,77 @@ #=============================================================================== -@get('queries') +QueryIdParameter = Annotated[ + str, + Parameter( + description=( + 'The ID of the competency query. ' + 'See [GET /competency/queries/](#get-/competency/queries) for the list of available queries.' + ), + examples=[Example(summary='Example query ID', value='1',)], + ), +] + +QueryRequestBody = Annotated[ + QueryRequest, + Body( + description='The competency query ID and the parameter values required by that query.', + schema_extra={ + 'example': { + 'query_id': '1', + 'parameters': [ + { + 'column': 'feature_id', + 'value': 'UBERON:0001759', + }, + { + 'column': 'source_id', + 'value': 'sckan-2026-02-11', + }, + ], + } + }, + ), +] + +#=============================================================================== + +@get( + 'queries', + description=('Retrieve all available competency query definitions.') +) async def competency_query_definitions(request: Request) -> list[QueryDefinitionSummary]: #======================================================================================= return await query_definitions(request) -@get('queries/{query_id:str}') -async def competency_query_definition(query_id: str, request: Request) -> QueryDefinitionDict: -#============================================================================================= +@get( + 'queries/{query_id:str}', + description='Retrieve a competency query definition by ID.' +) +async def competency_query_definition(query_id: QueryIdParameter, request: Request) -> QueryDefinitionDict: +#========================================================================================================== return await query_definition(query_id, request) -@post('query/') -async def competency_query(data: QueryRequest, request: Request) -> QueryResults|QueryError: +@post( + 'query/', + description=( + 'Execute a competency query. ' + 'The required parameters depend on the selected query_id. ' + 'See [GET /competency/queries/{query_id}](#get-/competency/queries/-query_id-) for parameter definitions. ' + 'See [GET /competency/queries/](#get-/competency/queries) for the list of available queries.' + ) +) +async def competency_query(data: QueryRequestBody, request: Request) -> QueryResults|QueryError: #=========================================================================================== result = await query(data, request) if 'error' in result: request.logger.warning(result["error"]) return result -@get('schema-version') +@get( + 'schema-version', + description=('Retrieve version details for the competency schema.') +) async def competency_schema_version(request: Request) -> dict[str, str|None]: #========================================================================== return await get_competency_schema_info(request.app) diff --git a/mapserver/server/flatmap.py b/mapserver/server/flatmap.py index 9ac70c9..79cd03e 100644 --- a/mapserver/server/flatmap.py +++ b/mapserver/server/flatmap.py @@ -34,9 +34,11 @@ from litestar.exceptions import HTTPException, NotFoundException from litestar.middleware import DefineMiddleware from litestar.middleware.compression import CompressionMiddleware -from litestar.params import FromQuery from litestar.response import File from litestar.status_codes import HTTP_206_PARTIAL_CONTENT, HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE +from litestar.openapi.spec import Example +from litestar.params import Parameter, QueryParameter +from typing import Annotated from PIL import Image @@ -51,6 +53,60 @@ #=============================================================================== +example_uuid = None +example_image = None +for flatmap in get_flatmap_list(): + if 'error' not in flatmap and 'uuid' in flatmap: + example_uuid = flatmap.get('uuid', flatmap['id']) + example_image = f'{flatmap['id']}.svg' + break + +UuidParameter = Annotated[ + str, + Parameter( + description=( + 'The UUID of a flatmap. Obtain valid UUIDs from the flatmap listing endpoint. ' + 'See [GET /](#get-/) for the list of available flatmaps.' + ), + examples=[Example(summary='Example UUID', value=example_uuid)], + ), +] + +PathIdParameter = Annotated[ + str, + Parameter( + description='The ID of a neuron population pathway.', + examples=[Example(value='ilxtr:neuron-type-aacar-10a')] + ), +] + +ImageParameter = Annotated[ + str, + Parameter( + description='The image filename located in the flatmap images directory.', + examples=[Example(value=example_image)], + ), +] + +ZParameter = Annotated[int, Parameter(description="Tile zoom level.", examples=[Example(value=6)])] +XParameter = Annotated[int, Parameter(description="Tile X coordinate.", examples=[Example(value=30)])] +YParameter = Annotated[int, Parameter(description="Tile Y coordinate.", examples=[Example(value=30)])] +LayerParameter = Annotated[str, Parameter(description='The name of the tile layer.', examples=[Example(value='index')])] + +ExtrasParameter = Annotated[ + str, + QueryParameter( + description=( + 'Optional extra entries to include in the returned index, separated by `;`. ' + 'Valid values are `mapAnnotations`, `mapLayers`, `mapMetadata`, `mapPathways`, and `mapStyle`.' + ), + examples=[Example(summary='Multiple extras', value='mapMetadata;mapStyle')], + required=False, + ), +] + +#=============================================================================== + """ The name of the log file from when the map was made """ @@ -91,7 +147,7 @@ def blank_tile(): #=============================================================================== #=============================================================================== -@get('/') +@get('/', description='Retrieve a list of available flatmaps.') async def flatmap_maps(request: Request) -> list: """ Get a list of available flatmaps. @@ -112,8 +168,15 @@ async def flatmap_maps(request: Request) -> list: #=============================================================================== -@get('flatmap/{map_uuid:str}/') -async def flatmap_index(request: Request, map_uuid: str, extras: FromQuery[str]='') -> dict|Response: +@get( + 'flatmap/{map_uuid:str}/', + description=( + 'Return a flatmap. ' + 'Use the Accept header to request RDF (text/turtle), SVG, or JSON.' + ) +) +async def flatmap_index(request: Request, map_uuid:UuidParameter, extras: ExtrasParameter='') -> dict|Response: + """ Return a representation of a flatmap. @@ -172,8 +235,11 @@ async def flatmap_index(request: Request, map_uuid: str, extras: FromQuery[str]= #=============================================================================== -@get('flatmap/{map_uuid:str}/log') -async def flatmap_maker_log(map_uuid: str) -> File: +@get( + 'flatmap/{map_uuid:str}/log', + description=('Retrieve the flatmap maker log for the specified flatmap.') +) +async def flatmap_maker_log(map_uuid: UuidParameter) -> File: path = pathlib.Path(settings['FLATMAP_ROOT']) / map_uuid / MAKER_LOG if not path.exists(): path = pathlib.Path(settings['FLATMAP_ROOT']) / map_uuid / OLD_MAKER_LOG @@ -184,15 +250,21 @@ async def flatmap_maker_log(map_uuid: str) -> File: #=============================================================================== -@get('flatmap/{map_uuid:str}/style') -async def flatmap_style(map_uuid: str) -> File: +@get( + 'flatmap/{map_uuid:str}/style', + description='Retrieve the map styling configuration for a flatmap.' +) +async def flatmap_style(map_uuid: UuidParameter) -> File: path = pathlib.Path(settings['FLATMAP_ROOT']) / map_uuid / 'style.json' return File(path=path, media_type=MediaType.JSON) #=============================================================================== -@get('flatmap/{map_uuid:str}/layers') -async def flatmap_layers(map_uuid: str) -> dict: +@get( + 'flatmap/{map_uuid:str}/layers', + description='Retrieve layer definitions and metadata for a flatmap.' +) +async def flatmap_layers(map_uuid: UuidParameter) -> dict: try: return json_map_metadata(map_uuid, 'layers') except IOError as err: @@ -200,8 +272,11 @@ async def flatmap_layers(map_uuid: str) -> dict: #=============================================================================== -@get('flatmap/{map_uuid:str}/metadata') -async def flatmap_metadata(map_uuid: str) -> dict: +@get( + 'flatmap/{map_uuid:str}/metadata', + description='Retrieve descriptive metadata for the specified flatmap.' +) +async def flatmap_metadata(map_uuid: UuidParameter) -> dict: try: return json_map_metadata(map_uuid, 'metadata') except IOError as err: @@ -210,8 +285,11 @@ async def flatmap_metadata(map_uuid: str) -> dict: #=============================================================================== #=============================================================================== -@get('flatmap/{map_uuid:str}/pathways') -async def flatmap_pathways(map_uuid: str) -> dict: +@get( + 'flatmap/{map_uuid:str}/pathways', + description='Retrieve pathway definitions and metadata for a flatmap.' +) +async def flatmap_pathways(map_uuid: UuidParameter) -> dict: try: return pathways(map_uuid) except IOError as err: @@ -230,8 +308,11 @@ async def flatmap_pathways(map_uuid: str) -> dict: 'taxons', ] -@get('flatmap/{map_uuid:str}/connectivity/{path_id:path}') -async def flatmap_connectivity(map_uuid: str, path_id: str) -> dict: +@get( + 'flatmap/{map_uuid:str}/connectivity/{path_id:path}', + description='Retrieve connectivity and anatomical features for a neuron population pathway.' +) +async def flatmap_connectivity(map_uuid: UuidParameter, path_id: PathIdParameter) -> dict: path_id = path_id[1:] # Remove leading '/'' try: path_data = pathways(map_uuid) @@ -266,8 +347,11 @@ async def flatmap_connectivity(map_uuid: str, path_id: str) -> dict: #=============================================================================== #=============================================================================== -@get('flatmap/{map_uuid:str}/images/{image:str}') -async def flatmap_image(map_uuid: str, image:str) -> Response: +@get( + 'flatmap/{map_uuid:str}/images/{image:str}', + description=('Retrieve an image file associated with the specified flatmap.') +) +async def flatmap_image(map_uuid: UuidParameter, image:ImageParameter) -> Response: path = pathlib.Path(settings['FLATMAP_ROOT']) / map_uuid / 'images' / image if not path.exists(): raise NotFoundException(detail=f'Missing image: {image}') @@ -275,8 +359,11 @@ async def flatmap_image(map_uuid: str, image:str) -> Response: #=============================================================================== -@get('flatmap/{map_uuid:str}/mvtiles/{z:int}/{x:int}/{y:int}') -async def flatmap_vector_tiles(map_uuid: str, z: int, y:int, x: int) -> Response: +@get( + 'flatmap/{map_uuid:str}/mvtiles/{z:int}/{x:int}/{y:int}', + description='Retrieve a vector map tile for the specified flatmap and tile coordinates.' +) +async def flatmap_vector_tiles(map_uuid: UuidParameter, z: ZParameter, y:YParameter, x: XParameter) -> Response: try: mbtiles = pathlib.Path(settings['FLATMAP_ROOT']) / map_uuid / 'index.mbtiles' tile_reader = MBTilesReader(mbtiles) @@ -312,11 +399,14 @@ def parse_range_header(header_value: str, file_size: int) -> tuple[int, int]: except ValueError: raise HTTPException(status_code=HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE) -@get([ - "flatmap/{map_uuid:str}/pmtiles/", - "flatmap/{map_uuid:str}/pmtiles/{layer:str}" -]) -async def flatmap_get_pmtiles(request: Request, map_uuid: str, layer: str='index') -> File: +@get( + [ + "flatmap/{map_uuid:str}/pmtiles/", + "flatmap/{map_uuid:str}/pmtiles/{layer:str}" + ], + description=('Retrieve a PMTiles archive or layer for a flatmap.') +) +async def flatmap_get_pmtiles(request: Request, map_uuid: UuidParameter, layer: LayerParameter='index') -> File: filename = f'{layer}.pmtiles' filepath = pathlib.Path(settings['FLATMAP_ROOT']) / map_uuid / filename if not filepath.exists(): @@ -349,8 +439,11 @@ async def flatmap_get_pmtiles(request: Request, map_uuid: str, layer: str='index #=============================================================================== -@get('flatmap/{map_uuid:str}/tiles/{layer:str}/{z:int}/{x:int}/{y:int}') -async def flatmap_image_tiles(map_uuid: str, layer: str, z: int, y:int, x: int) -> Response: +@get( + 'flatmap/{map_uuid:str}/tiles/{layer:str}/{z:int}/{x:int}/{y:int}', + description='Retrieve a raster tile for the specified flatmap layer and tile coordinates.' +) +async def flatmap_image_tiles(map_uuid: UuidParameter, layer: LayerParameter, z: ZParameter, y: XParameter, x: YParameter) -> Response: try: mbtiles = pathlib.Path(settings['FLATMAP_ROOT']) / map_uuid / f'{layer}.mbtiles' reader = MBTilesReader(mbtiles) @@ -363,8 +456,11 @@ async def flatmap_image_tiles(map_uuid: str, layer: str, z: int, y:int, x: int) #=============================================================================== -@get('flatmap/{map_uuid:str}/annotations') -async def flatmap_annotation(map_uuid: str) -> dict: +@get( + 'flatmap/{map_uuid:str}/annotations', + description='Retrieve flatmap annotations by map UUID.' +) +async def flatmap_annotation(map_uuid: UuidParameter) -> dict: try: return json_map_metadata(map_uuid, 'annotations') except IOError as err: @@ -375,8 +471,11 @@ async def flatmap_annotation(map_uuid: str) -> dict: """ Build and cache a hierarchy of anataomical terms used by a flatmap. """ -@get('flatmap/{map_uuid:str}/termgraph') -async def flatmap_termgraph(map_uuid: str) -> dict: +@get( + 'flatmap/{map_uuid:str}/termgraph', + description='Retrieve the anatomical term hierarchy for structures represented in the specified flatmap.' +) +async def flatmap_termgraph(map_uuid: UuidParameter) -> dict: try: anatomical_hierarchy = AnatomicalHierarchy() return anatomical_hierarchy.get_hierarchy(map_uuid) diff --git a/mapserver/server/knowledge.py b/mapserver/server/knowledge.py index 75ba59a..d0a722f 100644 --- a/mapserver/server/knowledge.py +++ b/mapserver/server/knowledge.py @@ -20,11 +20,12 @@ from dataclasses import dataclass import os -from typing import Optional +from typing import Annotated, Optional #=============================================================================== from litestar import get, MediaType, post, Request, Router +from litestar.params import Body from litestar.response import File #=============================================================================== @@ -38,16 +39,58 @@ @dataclass class QueryData: - sql: str - params: Optional[list[str]] = None + sql: Annotated[ + str, + Body(description='A read-only SQLite SQL statement to execute against the knowledge store.'), + ] + params: Annotated[ + Optional[list[str]], + Body(description='Values bound to positional `?` placeholders in `sql`, in order.'), + ] = None @dataclass class KnowledgeSourcesResponse: sources: list[str] +@dataclass +class ForeignKeyDefinition: + column: str + to_table: str + to_column: str + +@dataclass +class ColumnDefinition: + name: str + type: str + primary_key: bool + nullable: bool + +@dataclass +class TableDefinition: + name: str + columns: list[ColumnDefinition] + foreign_keys: list[ForeignKeyDefinition] + +@dataclass +class DatabaseSchemaResponse: + tables: list[TableDefinition] + #=============================================================================== #=============================================================================== +KnowledgeQueryBody = Annotated[ + QueryData, + Body( + description='SQL statement and positional parameter values for a knowledge-store query.', + schema_extra={ + 'example': { + 'sql': 'SELECT value FROM metadata WHERE name = ?', + 'params': ['schema_version'], + }, + }, + ), +] + def query_knowledge(sql: str, params: list[str]) -> dict: #======================================================== knowledge_store = KnowledgeStore(settings['FLATMAP_ROOT']) @@ -64,11 +107,61 @@ def get_knowledge_sources() -> list[str]: knowledge_store.close() return sources +def get_database_schema() -> DatabaseSchemaResponse: +#=================================================== + """ + Returns the flatmap server's knowledge base schema. + """ + tables_result = query_knowledge( + "SELECT name FROM sqlite_schema WHERE type='table' AND name NOT LIKE 'sqlite_%';", + [] + ) + if "error" in tables_result or "values" not in tables_result: + return DatabaseSchemaResponse(tables=[]) + + table_names = [row[0] for row in tables_result["values"]] + schema_tables = [] + for table_name in table_names: + # Fetch Foreign Keys via table-valued function syntax + # Format returns: (id, seq, table, from, to, on_update, on_delete, match) + fk_sql = f"SELECT * FROM pragma_foreign_key_list('{table_name}');" + fk_result = query_knowledge(fk_sql, []) + foreign_keys = [ + ForeignKeyDefinition(column=row[3], to_table=row[2], to_column=row[4]) + for row in fk_result["values"] if row is not None + ] if "values" in fk_result else [] + # Fetch Columns via table-valued function syntax + # Format returns: (cid, name, type, notnull, dflt_value, pk) + col_sql = f"SELECT name, type, pk, [notnull] FROM pragma_table_info('{table_name}');" + col_result = query_knowledge(col_sql, []) + columns = [ + ColumnDefinition( + name=row[0], + type=row[1] if row[1] else "TEXT", + primary_key=bool(row[2]), + nullable=not bool(row[3]) + ) + for row in col_result["values"] + ] if "values" in col_result else [] + + schema_tables.append(TableDefinition( + name=table_name, + columns=columns, + foreign_keys=foreign_keys + )) + return DatabaseSchemaResponse(tables=schema_tables) + #=============================================================================== #=============================================================================== -@post('query/') -async def knowledge_query(data: QueryData, request: Request) -> dict: +@post( + 'query/', + description=( + 'Execute a read-only SQL query against the flatmap knowledge store. ' + 'Use [GET /knowledge/schema](#get-/knowledge/schema) to inspect the available tables and columns.' + ), +) +async def knowledge_query(data: KnowledgeQueryBody, request: Request) -> dict: #==================================================================== """ Query the flatmap server's knowledge base. @@ -85,7 +178,10 @@ async def knowledge_query(data: QueryData, request: Request) -> dict: request.logger.warning(f'SQL: {result["error"]}') return result -@get('sources') +@get( + 'sources', + description='List the available SCKAN knowledge-source versions, newest first.', +) async def knowledge_sources() -> KnowledgeSourcesResponse: #========================================================= """ @@ -98,13 +194,19 @@ async def knowledge_sources() -> KnowledgeSourcesResponse: sources = get_knowledge_sources() return KnowledgeSourcesResponse(sources) -@get('sparcterms') +@get( + 'sparcterms', + description='Download the cached SPARC anatomical hierarchy as JSON.', +) async def knowledge_sparcterms() -> File: #======================================== filename = os.path.join(settings['FLATMAP_ROOT'], CACHED_SPARC_HIERARCHY) return File(path=filename, media_type=MediaType.JSON) -@get('schema-version') +@get( + 'schema-version', + description='Return the schema version of the flatmap knowledge store.', +) async def knowledge_schema_version(request: Request) -> dict: #============================================================ """ @@ -115,6 +217,17 @@ async def knowledge_schema_version(request: Request) -> dict: request.logger.warning(f'SQL: {result["error"]}') return {'version': result['values'][0][0]} +@get( + 'schema', + description='Return all knowledge-store tables, columns, and foreign-key relationships.', +) +async def knowledge_schema() -> DatabaseSchemaResponse: +#====================================================== + """ + Return the complete relational schema blueprint of the database. + """ + return get_database_schema() + #=============================================================================== #=============================================================================== @@ -122,6 +235,7 @@ async def knowledge_schema_version(request: Request) -> dict: path="/knowledge", route_handlers=[ knowledge_query, + knowledge_schema, knowledge_schema_version, knowledge_sources, knowledge_sparcterms diff --git a/mapserver/server/maker.py b/mapserver/server/maker.py index 3fcb2d9..998a9aa 100644 --- a/mapserver/server/maker.py +++ b/mapserver/server/maker.py @@ -21,7 +21,7 @@ from collections.abc import AsyncGenerator from datetime import datetime import sys -from typing import Any +from typing import Annotated, Any #=============================================================================== @@ -31,6 +31,8 @@ from litestar import Litestar, WebSocket, websocket from litestar.exceptions import WebSocketDisconnect from litestar.handlers import send_websocket_stream +from litestar.openapi.spec import Example +from litestar.params import Body, Parameter #=============================================================================== @@ -60,11 +62,51 @@ def terminate(): map_maker.terminate() map_maker = None +#=============================================================================== + +MakerRequestBody = Annotated[ + MakerData, + Body( + description='The manifest source and options for generating a flatmap.', + schema_extra={ + 'example': { + 'source': 'https://github.com/AnatomicMaps/human-flatmap', + 'manifest': 'female.manifest.json', + 'commit': 'main', + 'force': False, + }, + }, + ), +] + +ProcessIdParameter = Annotated[ + int, + Parameter( + description='The operating-system process ID of the map-generation process.', + examples=[Example(value=12345)], + ), +] + +MakerIdParameter = Annotated[ + str, + Parameter( + description='The server-assigned ID of the map-generation process.', + examples=[Example(value='f4a76fe4-8fd1-4f19-839b-6e08ca0cee30')], + ), +] + #=============================================================================== #=============================================================================== -@post('/map') -async def make_map(data: MakerData) -> MakerResponse|Response: +@post( + '/map', + description=( + 'Start a flatmap generation process. Requires `Authorization: Bearer TOKEN`. ' + 'See the [flatmap-server README](https://github.com/AnatomicMaps/flatmap-server#authentication) ' + 'for authentication details.' + ), +) +async def make_map(data: MakerRequestBody) -> MakerResponse|Response: #============================================================= """ Generate a flatmap. @@ -88,8 +130,11 @@ async def make_map(data: MakerData) -> MakerResponse|Response: result = await map_maker.make(data) return MakerResponse(result.status, result.id, result.pid, data.source, data.commit) -@get('/process-log/{pid:int}') -async def make_process_log(pid: int) -> dict|Response: +@get( + '/process-log/{pid:int}', + description='Retrieve the log for a map-generation process. Requires `Authorization: Bearer TOKEN`.', +) +async def make_process_log(pid: ProcessIdParameter) -> dict|Response: #===================================================== """ Return the log of a map generation process @@ -104,8 +149,11 @@ async def make_process_log(pid: int) -> dict|Response: 'log': log } -@get('/log/{id:str}') -async def make_status_log(id: str) -> MakerLogResponse|Response: +@get( + '/log/{id:str}', + description='Retrieve the process status and unseen log records. Requires `Authorization: Bearer TOKEN`.', +) +async def make_status_log(id: MakerIdParameter) -> MakerLogResponse|Response: #================================================================================== """ Return the status of a map generation process along with unseen log records @@ -118,8 +166,11 @@ async def make_status_log(id: str) -> MakerLogResponse|Response: status = map_maker.status(id) return MakerLogResponse(status.status, status.id, status.pid, log_data, str(datetime.now())) -@get('/status/{id:str}') -async def make_status(id: str) -> MakerStatus|Response: +@get( + '/status/{id:str}', + description='Retrieve the status of a map-generation process. Requires `Authorization: Bearer TOKEN`.', +) +async def make_status(id: MakerIdParameter) -> MakerStatus|Response: #====================================================== """ Get the status of a map generation process.