Module: Web API Backend¶
The Mastoscore Web API provides REST endpoints for the Backstage web interface. It wraps the core Mastoscore functionality in HTTP endpoints. This is mainly used by the backstage app. This is totally, wildly insecure! Never ever expose this to the internet! Yes, it's HTTP. No, it's not meant to have random strangers invoking it.
- Base URL:
http://localhost:5000/api - OpenAPI 3.0 specification:
webapi/openapi.yaml - Launch it alone with:
uv run -m webapi.app - Normally:
bash scripts/backstage.shto launch both backend and front end
As a general principle, you don't ask for a specific thing by filename (e.g., a graph file or an alt text file). You pass in the config file that represents the event, and then all the parameters in the config determine what it does. Pretty much every API call takes a config file as a parameter.
Configuration Management¶
GET /config/list¶
List all available configuration files. This is not dynamic. So if you make new files, you need to call it again.
Response: Array of config objects with name, path, hashtag, modified timestamp.
GET /config/{name}¶
Get specific configuration file contents.
Parameters:
- name (path) - Path to config file relative to ini directory
Response: Configuration object with all sections.
POST /config/{name}¶
Create new configuration file.
Parameters:
- name (path) - Path where config should be created
Request Body: Configuration object. This should be a full INI file. This is an example of why this web api is totally not suitable for connecting to the internet. This does basically no input validation and will probably happily write any file you have access to.
Response: Success message with created path.
PUT /config/{name}¶
Update existing configuration file.
Parameters:
- name (path) - Path to config file to update
Request Body: Configuration object. Just like the POST version, this expects the full content of the INI file.
Response: Success message.
DELETE /config/{name}¶
Delete configuration file.
Parameters:
- name (path) - Path to config file to delete
Response: Success message.
Running Mastoscore¶
Fetching Toots¶
This is how you kick off, and then monitor fetching a lot of toots. A job_id is used for tracking when launching or checking status. You can cancel a set of fetches that are running, you can check to see if fetching is done, and you can reset to wipe out the files that were fetched.
POST /fetch¶
Start asynchronous fetch operation to collect toots from Mastodon servers.
Request Body:
- config_file (required) - Path to configuration file
- mock (optional) - Use mock backend for testing
Response: Job ID and status.
POST /fetch/cancel¶
Cancel a running fetch job. It will set a cancel flag and each thread checks that after each API call. Typically will die within a few seconds.
Request Body:
- job_id (required) - ID of job to cancel
Response: Success status and partial results.
POST /fetch/reset¶
Delete all fetch data files for a configuration. It reads a config file to figure out what data directory and what hashtag are used to name files.
Request Body:
- config_file (required) - Path to configuration file
Response: List of deleted files and total size.
POST /fetch/ready¶
Check if fetched data is ready for analysis.
Request Body:
- config_file (required) - Path to configuration file
Response: Ready status and file information.
Analyse¶
Analysing is done when you have a whole pile of json files that were created by fetching. It only looks at the presence of the fetch.json file to assume things are done. There's not much to this. You just do the analysis once.
POST /analyse¶
Execute analysis operation on fetched data.
Request Body:
- config_file (required) - Path to configuration file
Response: Analysis results JSON. This is used by the backstage UI to display them for review.
Post¶
This is how you post all the toots with the analysis. Again, not much to do. A single API call that does it.
POST /post¶
Post analysis results to Mastodon. Unlike the original CLI version, this will post everything: text analysis, top posts, and also all the graphics.
Request Body:
- config_file (required) - Path to configuration file
Response: Returns a JSON structure with links to all the different posts that were made. This is used by the front end to make a list of posts.
Graphs¶
There are 2 graphing modules. One is called "graph" and it makes the histogram. The other is "wordcloud" and it makes the wordcloud. Each of them has a method to trigger the creation, then a method to fetch the graphic and a method to fetch the alt text description.
POST /graph¶
Trigger the creation of the histogram image file. For historical reasons, this is called the graph, as opposed to the wordcloud.
Request Body:
- config_file (required) - Path to configuration file
Response: Success status.
POST /graph/image¶
Fetch the histogram image that was generated.
Request Body:
- config_file (required) - Path to configuration file
Response: PNG image file.
POST /graph/description¶
Get graph alt text description for accessibility.
Request Body:
- config_file (required) - Path to configuration file
Response: Description text.
POST /wordcloud¶
Trigger the creation of the wordcloud image file.
Request Body:
- config_file (required) - Path to configuration file
Response: Job ID and status.
POST /wordcloud/image¶
Get generated wordcloud image file.
Request Body:
- config_file (required) - Path to configuration file
Response: PNG image file.
POST /wordcloud/description¶
Get wordcloud alt text description for accessibility.
Request Body:
- config_file (required) - Path to configuration file
Response: Description text.
Blog Post Creation¶
This endpoint helps with creating the blog post. It can check to see if the blog post is already created. It can fetch the content of the blog post, and it has an interface to searching The Movie Database (themoviedb.org) to fetch movie posters. It also has a hard-wired copying method that assumes you have a Hugo blog post set up at ../{hashtag}-gallery. I only regularly do this for 2 different hashtags, and both have galleries done this way.
POST /blog¶
Generate Hugo-compatible markdown blog post.
Request Body:
- config_file (required) - Path to configuration file
- additional_tags (optional) - Array of extra tags
Response: Success status and file path.
POST /blog/ready¶
Check if blog post has been generated. This is
Request Body:
- config_file (required) - Path to configuration file
Response: Ready status and file information.
POST /blog/content¶
Get blog post markdown content.
Request Body:
- config_file (required) - Path to configuration file
Response: Markdown content.
POST /blog/search-posters¶
Trigger a search for movie posters using the TMDb API.
Request Body:
- query (required) - Movie title to search
- year (optional) - Release year
Response: Array of poster results with URLs and metadata.
POST /blog/select-poster¶
Download and save selected movie poster.
Request Body:
- config_file (required) - Path to configuration file
- poster_url (required) - URL of poster to download
Response: Success status.
POST /blog/poster¶
Check if poster image exists for configuration. It looks for a file named thumb.jpg. If that exists, it presumes it is a movie poster and returns true.
Request Body:
- config_file (required) - Path to configuration file
Response: Exists status.
POST /blog/poster/image¶
Get poster image file.
Request Body:
- config_file (required) - Path to configuration file
Response: JPEG image file.
POST /blog/posts¶
Get posted URLs from posts.json.
Request Body:
- config_file (required) - Path to configuration file
Response: Array of posted URLs.
Job Monitoring¶
There is only one asynchronous action right now, and that's fetching. So this is how you poll to get the status of a job.
GET /jobs/{jobId}¶
Check status and progress of a running or completed job.
Parameters:
- jobId (path) - UUID of job to check
Response: Job status object with progress information.
Results¶
GET /results/{configName}¶
Get analysis results for a configuration.
Parameters:
- configName (path) - Configuration name
Response: Analysis results JSON.
Architecture¶
The Web API is built with:
- Flask - Python web framework
- Flask-CORS - Cross-origin resource sharing
- Threading - Background job execution
Jobs run asynchronously in background threads. Long-running operations (fetch, analyse) return immediately with a job ID that can be polled for status.
Reference Details¶
For more information, see the webapi details.