Stashapp-tag-importer

:placard: Summary Creates tags and aliases, resolves tag conflicts, and updates tag titles and descriptions from Stashbox (StashDB) to your local Stash instance.
:link: Repository https://github.com/soundchaser128/stashapp-tag-importer/blob/main/stash_tag_importer/main.py

stashapp-tag-importer

Creates tags and aliases, resolves tag conflicts, and updates tag titles and descriptions from Stashbox (StashDB) to your local Stash instance. It can be run periodically to perform a one way sync to keep your Stash instance up to date with Stashbox (StashDB).

Warning - Back Up Stash Instance Before Use

  • This script is very invasive and makes thousands of changes to your database.
  • Before using this script, back up your Stash instance.
    • Go to Settings > Tasks > Backup, then perform both Backup and Download Backup actions.
    • Make sure you are familiar with the restore process.
    • I would recommend testing out a restore before using this script.
  • This was developed and tested against Stash v0.24.3.
    • If you are on something older, please update.
    • If you are on something newer, I cannot stress enough, please perform a backup before using this script.

Known Issues

  • Tags on Stashbox (StashDB) can have alias collisions if the same alias is associated with two or more tags. stashapp-tag-importer will ping pong aliases between tags on your local Stash instance when this occurs.
    • The only way to solve this is to submit an edit on Stashbox (StashDB) to remove the the duplicate aliases until only one remains on the correct tag.

Features

  • Stat logging and log output of changes to file ./stashdb_tag_importer.log.
  • Caches tags from StashDB to local .json file for offline processing.
    • Automatically redownloads tags from StashDB if the StashDB tag count differs from local .json cache.
  • Error handling for Stash API so operations aren’t missed due to random Stash Database locks or other issues.
  • Smart resolution of the following cases.
    • Local Tag does not exist.
      • Create tag.
    • Local Tag has alias that matches a StashDB tag.
      • Remove alias from old local tag.
      • Create tag.
      • Add new tag to all scenes, markers, galleries, and performers with old tag applied.
    • Local Tag exists, but should be alias of StashDB Tag.
      • Merge tag into main tag.
    • Alias for existing Local Tag does not exist.
      • Add alias to existing tag.
    • Alias already associated with different Local Tag.
      • Remove alias from incorrect local tag.
      • Add alias to correct local tag.
      • Add correct tag to all scenes, markers, galleries, and performers with incorrect tag applied.
    • Local Tag Name and / or Description is out of date.
      • Update Tag Name and / or Description.

Installation

  • Make sure you have Python 3.10 or higher installed.
  • Install poetry.
curl -sSL https://install.python-poetry.org | python3 -
  • Clone or download this repository.
  • In the repo, rename the .env.example file to .env, then edit it to include your Stashbox endpoint and API key, and your local Stash instance URL and API key.
  • In the repo, run the following command to install required dependencies.
poetry install

Usage

  • In the repo, run the following command to execute the script.
poetry run python stash_tag_importer/main.py

I’m getting an error when trying to run this. I updated Stash to v29.3 and I’m not sure if that’s the reason this tool broke or if it has something to do with the StashDB API changing. If anyone can provide a fix, I would greatly appreciate it!

dVariables: {'filter': {'per_page': -1, 'sort': 'title', 'direction': 'ASC', 'q': ''}, 'scene_filter': {'tags': {'value': '554', 'modifier': 'INCLUDES'}}}
25-11-09 14:59:11 ERROR: API Failure on Payload:
25-11-09 14:59:11 ERROR: {'tags': {'value': '554', 'modifier': 'INCLUDES'}}
25-11-09 14:59:11 ERROR: Traceback (most recent call last):
  File "C:\Users\User\Documents\PycharmProjects\stashapp-tag-importer\stash_tag_importer\main.py", line 190, in stash_api_call
    return stash_api.find_scenes(payload, sorting)
  File "C:\Users\User\Documents\PycharmProjects\stashapp-tag-importer\.venv\lib\site-packages\stashapi\stashapp.py", line 1659, in find_scenes
    result = self.call_GQL(query, variables, callback=callback)
  File "C:\Users\User\Documents\PycharmProjects\stashapp-tag-importer\.venv\lib\site-packages\stashapi\stashapp.py", line 221, in call_GQL
    return self._GQL(query, variables)
  File "C:\Users\User\Documents\PycharmProjects\stashapp-tag-importer\.venv\lib\site-packages\stashapi\classes.py", line 227, in _GQL
    return self._handle_GQL_response(response)
  File "C:\Users\User\Documents\PycharmProjects\stashapp-tag-importer\.venv\lib\site-packages\stashapi\classes.py", line 270, in _handle_GQL_response
    raise Exception(error_msg)
Exception: 422 Unprocessable Entity query failed. v0.29.3-7716

25-11-09 14:59:11 INFO: Sleeping for 10 seconds, then trying API call again.

Turns out I was just using an old version of the stashapi library. I upgraded from Python 3.10 to 3.14 and created a new virtual environment, redownloaded all the dependencies, then it worked! Hopefully this helps if anyone else runs into this issue.

1 Like