Fomulated potentially useful openapi spec and json schema.
This commit is contained in:
471
software/src/microdot/tonberry.openapi.v1.yml
Normal file
471
software/src/microdot/tonberry.openapi.v1.yml
Normal file
@@ -0,0 +1,471 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: Tonberry API
|
||||
description: API for managing audio files, playlists, and NFC tags on the Tonberry device
|
||||
version: 1.0.0
|
||||
|
||||
servers:
|
||||
- url: /v1
|
||||
description: Version 1
|
||||
|
||||
paths:
|
||||
/api/filesystem:
|
||||
get:
|
||||
summary: List contents of a directory
|
||||
parameters:
|
||||
- name: path
|
||||
in: query
|
||||
required: false
|
||||
description: Directory path relative to root. If omitted, lists root directory.
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Directory contents
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
path:
|
||||
type: string
|
||||
directories:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
path:
|
||||
type: string
|
||||
files:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/AudioFile'
|
||||
security:
|
||||
- basicAuth: []
|
||||
|
||||
/api/filesystem/directory:
|
||||
post:
|
||||
summary: Create a new directory
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
path:
|
||||
type: string
|
||||
description: Full path of the directory to create
|
||||
required:
|
||||
- path
|
||||
responses:
|
||||
'201':
|
||||
description: Directory created
|
||||
delete:
|
||||
summary: Delete a directory
|
||||
parameters:
|
||||
- name: path
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'204':
|
||||
description: Directory deleted
|
||||
|
||||
/api/filesystem/files:
|
||||
post:
|
||||
summary: Upload one or more audio files
|
||||
parameters:
|
||||
- name: path
|
||||
in: query
|
||||
required: false
|
||||
description: Target directory path. If omitted, files will be uploaded to root.
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
multipart/form-data:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
files:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: binary
|
||||
responses:
|
||||
'201':
|
||||
description: Files uploaded. IDs are automatically generated.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/AudioFile'
|
||||
|
||||
/api/filesystem/files/{fileId}:
|
||||
get:
|
||||
summary: Get audio file details
|
||||
parameters:
|
||||
- name: fileId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
'200':
|
||||
description: Audio file details
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AudioFile'
|
||||
delete:
|
||||
summary: Delete an audio file
|
||||
parameters:
|
||||
- name: fileId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
'204':
|
||||
description: Audio file deleted
|
||||
|
||||
/api/playlists:
|
||||
get:
|
||||
summary: List all playlists
|
||||
responses:
|
||||
'200':
|
||||
description: List of playlists
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Playlist'
|
||||
post:
|
||||
summary: Create a new playlist
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
audio_files:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: ID of an existing audio file
|
||||
required:
|
||||
- name
|
||||
- audio_files
|
||||
responses:
|
||||
'201':
|
||||
description: Playlist created. ID is automatically generated.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Playlist'
|
||||
|
||||
/api/playlists/{playlistId}:
|
||||
get:
|
||||
summary: Get playlist details
|
||||
parameters:
|
||||
- name: playlistId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
'200':
|
||||
description: Playlist details
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Playlist'
|
||||
put:
|
||||
summary: Update a playlist
|
||||
parameters:
|
||||
- name: playlistId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
audio_files:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: ID of an existing audio file
|
||||
required:
|
||||
- name
|
||||
- audio_files
|
||||
responses:
|
||||
'200':
|
||||
description: Playlist updated
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Playlist'
|
||||
delete:
|
||||
summary: Delete a playlist
|
||||
parameters:
|
||||
- name: playlistId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
'204':
|
||||
description: Playlist deleted
|
||||
|
||||
/api/nfc-tags:
|
||||
get:
|
||||
summary: List all NFC tags
|
||||
responses:
|
||||
'200':
|
||||
description: List of NFC tags
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/NfcTag'
|
||||
post:
|
||||
summary: Register a new NFC tag
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NfcTag'
|
||||
responses:
|
||||
'201':
|
||||
description: NFC tag registered
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NfcTag'
|
||||
|
||||
/api/nfc-tags/{uid}:
|
||||
get:
|
||||
summary: Get NFC tag details
|
||||
parameters:
|
||||
- name: uid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: NFC tag details
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NfcTag'
|
||||
put:
|
||||
summary: Update NFC tag
|
||||
parameters:
|
||||
- name: uid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NfcTag'
|
||||
responses:
|
||||
'200':
|
||||
description: NFC tag updated
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NfcTag'
|
||||
delete:
|
||||
summary: Unregister an NFC tag
|
||||
parameters:
|
||||
- name: uid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'204':
|
||||
description: NFC tag unregistered
|
||||
|
||||
/api/playback/control:
|
||||
post:
|
||||
summary: Control playback
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
action:
|
||||
type: string
|
||||
enum: [play, pause, stop, next, previous]
|
||||
target_type:
|
||||
type: string
|
||||
enum: [audio_file, playlist]
|
||||
target_id:
|
||||
type: string
|
||||
format: uuid
|
||||
required: [action]
|
||||
responses:
|
||||
'200':
|
||||
description: Playback control successful
|
||||
|
||||
components:
|
||||
schemas:
|
||||
DirectoryEntry:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
path:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- path
|
||||
|
||||
DirectoryListing:
|
||||
type: object
|
||||
properties:
|
||||
path:
|
||||
type: string
|
||||
directories:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/DirectoryEntry'
|
||||
files:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/AudioFile'
|
||||
required:
|
||||
- path
|
||||
- directories
|
||||
- files
|
||||
|
||||
PlaybackPosition:
|
||||
type: object
|
||||
properties:
|
||||
position_seconds:
|
||||
type: number
|
||||
device_uptime:
|
||||
type: number
|
||||
required:
|
||||
- position_seconds
|
||||
|
||||
AudioFile:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
readOnly: true
|
||||
description: Server-generated unique identifier
|
||||
filename:
|
||||
type: string
|
||||
size_bytes:
|
||||
type: integer
|
||||
duration_seconds:
|
||||
type: number
|
||||
last_played_uptime:
|
||||
type: number
|
||||
playback_position:
|
||||
$ref: '#/components/schemas/PlaybackPosition'
|
||||
status:
|
||||
type: string
|
||||
enum: [ready, playing, paused]
|
||||
required:
|
||||
- id
|
||||
- filename
|
||||
|
||||
Playlist:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
readOnly: true
|
||||
description: Server-generated unique identifier
|
||||
name:
|
||||
type: string
|
||||
audio_files:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/AudioFile'
|
||||
current_track_index:
|
||||
type: integer
|
||||
minimum: 0
|
||||
last_played_uptime:
|
||||
type: number
|
||||
playback_position:
|
||||
$ref: '#/components/schemas/PlaybackPosition'
|
||||
status:
|
||||
type: string
|
||||
enum: [ready, playing, paused]
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
- audio_files
|
||||
|
||||
NfcTag:
|
||||
type: object
|
||||
properties:
|
||||
uid:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
linked_type:
|
||||
type: string
|
||||
enum: [audio_file, playlist]
|
||||
linked_id:
|
||||
type: string
|
||||
format: uuid
|
||||
required:
|
||||
- uid
|
||||
- linked_type
|
||||
- linked_id
|
||||
|
||||
securitySchemes:
|
||||
basicAuth:
|
||||
type: http
|
||||
scheme: basic
|
||||
description: Basic authentication using username and password
|
||||
|
||||
security:
|
||||
- basicAuth: []
|
||||
84
software/src/microdot/tonberry.schema.json
Normal file
84
software/src/microdot/tonberry.schema.json
Normal file
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"PlaybackPosition": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"position_seconds": { "type": "number" },
|
||||
"device_uptime": { "type": "number" }
|
||||
},
|
||||
"required": ["position_seconds"]
|
||||
},
|
||||
"AudioFile": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": { "type": "string", "format": "uuid" },
|
||||
"filename": { "type": "string" },
|
||||
"size_bytes": { "type": "integer" },
|
||||
"duration_seconds": { "type": "number" },
|
||||
"last_played_uptime": { "type": "number" },
|
||||
"playback_position": { "$ref": "#/definitions/PlaybackPosition" },
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["ready", "playing", "paused"]
|
||||
}
|
||||
},
|
||||
"required": ["id", "filename"]
|
||||
},
|
||||
"Playlist": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": { "type": "string", "format": "uuid" },
|
||||
"name": { "type": "string" },
|
||||
"audio_files": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/AudioFile" }
|
||||
},
|
||||
"current_track_index": { "type": "integer", "minimum": 0 },
|
||||
"last_played_uptime": { "type": "number" },
|
||||
"playback_position": { "$ref": "#/definitions/PlaybackPosition" },
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["ready", "playing", "paused"]
|
||||
}
|
||||
},
|
||||
"required": ["id", "name", "audio_files"]
|
||||
},
|
||||
"NfcTag": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"uid": { "type": "string" },
|
||||
"name": { "type": "string" },
|
||||
"linked_type": {
|
||||
"type": "string",
|
||||
"enum": ["audio_file", "playlist"]
|
||||
},
|
||||
"linked_id": { "type": "string", "format": "uuid" }
|
||||
},
|
||||
"required": ["uid", "linked_type", "linked_id"]
|
||||
},
|
||||
"DirectoryEntry": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"path": { "type": "string" }
|
||||
},
|
||||
"required": ["name", "path"]
|
||||
},
|
||||
"DirectoryListing": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": { "type": "string" },
|
||||
"directories": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/DirectoryEntry" }
|
||||
},
|
||||
"files": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/AudioFile" }
|
||||
}
|
||||
},
|
||||
"required": ["path", "directories", "files"]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user