diff --git a/.beamignore b/.beamignore new file mode 100644 index 0000000..cadccff --- /dev/null +++ b/.beamignore @@ -0,0 +1,43 @@ +# Ignore local scripts and data +create-data/ +sounds/ +*.wav +*.mp3 + +# Ignore images and documentation +images/ +*.png + +# Ignore virtual environment and local config +venv/ +.env +__pycache__/ +*.pyc +*.pyo +*.pyd + +# Ignore IDE-specific files +.idea/ +.vscode/ +*.swp +*.swo + +# Ignore logs and temporary files +*.log +*.tmp +.DS_Store + +# Ignore Git files +.git/ +.gitignore + +# Ignore Docker and local build files +Dockerfile + +# Ignore license and README (optional, if not needed in deployment) +LICENSE +README.md + +# Ignore local parameters and requirements (if handled by Beam) +parameters.json +requirements.txt diff --git a/.gitignore b/.gitignore index 487628d..cff6260 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.DS_Store .ei-block-config out* +input* scratchpad.py *test* *dataset diff --git a/.venv-beam/bin/Activate.ps1 b/.venv-beam/bin/Activate.ps1 new file mode 100644 index 0000000..b49d77b --- /dev/null +++ b/.venv-beam/bin/Activate.ps1 @@ -0,0 +1,247 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/.venv-beam/bin/activate b/.venv-beam/bin/activate new file mode 100644 index 0000000..5db50c7 --- /dev/null +++ b/.venv-beam/bin/activate @@ -0,0 +1,69 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null + fi + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1="(.venv-beam) ${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT="(.venv-beam) " + export VIRTUAL_ENV_PROMPT +fi + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null +fi diff --git a/.venv-beam/bin/activate.csh b/.venv-beam/bin/activate.csh new file mode 100644 index 0000000..e08e964 --- /dev/null +++ b/.venv-beam/bin/activate.csh @@ -0,0 +1,26 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = "(.venv-beam) $prompt" + setenv VIRTUAL_ENV_PROMPT "(.venv-beam) " +endif + +alias pydoc python -m pydoc + +rehash diff --git a/.venv-beam/bin/activate.fish b/.venv-beam/bin/activate.fish new file mode 100644 index 0000000..4ff6bd4 --- /dev/null +++ b/.venv-beam/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/); you cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + set -e _OLD_FISH_PROMPT_OVERRIDE + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + end + + set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV "/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# Unset PYTHONHOME if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # Save the current fish_prompt function as the function _old_fish_prompt. + functions -c fish_prompt _old_fish_prompt + + # With the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command. + set -l old_status $status + + # Output the venv prompt; color taken from the blue of the Python logo. + printf "%s%s%s" (set_color 4B8BBE) "(.venv-beam) " (set_color normal) + + # Restore the return status of the previous command. + echo "exit $old_status" | . + # Output the original/"old" prompt. + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" + set -gx VIRTUAL_ENV_PROMPT "(.venv-beam) " +end diff --git a/.venv-beam/bin/beam b/.venv-beam/bin/beam new file mode 100755 index 0000000..1436066 --- /dev/null +++ b/.venv-beam/bin/beam @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from beam.cli.main import cli +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(cli()) diff --git a/.venv-beam/bin/beta9 b/.venv-beam/bin/beta9 new file mode 100755 index 0000000..d170a0f --- /dev/null +++ b/.venv-beam/bin/beta9 @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from beta9.cli.main import start +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(start()) diff --git a/.venv-beam/bin/black b/.venv-beam/bin/black new file mode 100755 index 0000000..b77bb52 --- /dev/null +++ b/.venv-beam/bin/black @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from black import patched_main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(patched_main()) diff --git a/.venv-beam/bin/blackd b/.venv-beam/bin/blackd new file mode 100755 index 0000000..1a61457 --- /dev/null +++ b/.venv-beam/bin/blackd @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from blackd import patched_main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(patched_main()) diff --git a/.venv-beam/bin/f2py b/.venv-beam/bin/f2py new file mode 100755 index 0000000..3c92e35 --- /dev/null +++ b/.venv-beam/bin/f2py @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from numpy.f2py.f2py2e import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/f2py3 b/.venv-beam/bin/f2py3 new file mode 100755 index 0000000..3c92e35 --- /dev/null +++ b/.venv-beam/bin/f2py3 @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from numpy.f2py.f2py2e import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/f2py3.10 b/.venv-beam/bin/f2py3.10 new file mode 100755 index 0000000..3c92e35 --- /dev/null +++ b/.venv-beam/bin/f2py3.10 @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from numpy.f2py.f2py2e import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/fastapi b/.venv-beam/bin/fastapi new file mode 100755 index 0000000..db9b9a7 --- /dev/null +++ b/.venv-beam/bin/fastapi @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from fastapi.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/hf b/.venv-beam/bin/hf new file mode 100755 index 0000000..bc807ed --- /dev/null +++ b/.venv-beam/bin/hf @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from huggingface_hub.cli.hf import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/huggingface-cli b/.venv-beam/bin/huggingface-cli new file mode 100755 index 0000000..320f1d4 --- /dev/null +++ b/.venv-beam/bin/huggingface-cli @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from huggingface_hub.commands.huggingface_cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/isort b/.venv-beam/bin/isort new file mode 100755 index 0000000..a667d1e --- /dev/null +++ b/.venv-beam/bin/isort @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from isort.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/isort-identify-imports b/.venv-beam/bin/isort-identify-imports new file mode 100755 index 0000000..07b4c34 --- /dev/null +++ b/.venv-beam/bin/isort-identify-imports @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from isort.main import identify_imports_main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(identify_imports_main()) diff --git a/.venv-beam/bin/markdown-it b/.venv-beam/bin/markdown-it new file mode 100755 index 0000000..e68d4b9 --- /dev/null +++ b/.venv-beam/bin/markdown-it @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from markdown_it.cli.parse import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/normalizer b/.venv-beam/bin/normalizer new file mode 100755 index 0000000..58f8b47 --- /dev/null +++ b/.venv-beam/bin/normalizer @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from charset_normalizer.cli import cli_detect +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(cli_detect()) diff --git a/.venv-beam/bin/pip b/.venv-beam/bin/pip new file mode 100755 index 0000000..49730cd --- /dev/null +++ b/.venv-beam/bin/pip @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/pip3 b/.venv-beam/bin/pip3 new file mode 100755 index 0000000..49730cd --- /dev/null +++ b/.venv-beam/bin/pip3 @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/pip3.10 b/.venv-beam/bin/pip3.10 new file mode 100755 index 0000000..49730cd --- /dev/null +++ b/.venv-beam/bin/pip3.10 @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/pygmentize b/.venv-beam/bin/pygmentize new file mode 100755 index 0000000..c1465e7 --- /dev/null +++ b/.venv-beam/bin/pygmentize @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from pygments.cmdline import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/tiny-agents b/.venv-beam/bin/tiny-agents new file mode 100755 index 0000000..d7483c6 --- /dev/null +++ b/.venv-beam/bin/tiny-agents @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from huggingface_hub.inference._mcp.cli import app +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(app()) diff --git a/.venv-beam/bin/tqdm b/.venv-beam/bin/tqdm new file mode 100755 index 0000000..c24acc8 --- /dev/null +++ b/.venv-beam/bin/tqdm @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from tqdm.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/transformers-cli b/.venv-beam/bin/transformers-cli new file mode 100755 index 0000000..0298109 --- /dev/null +++ b/.venv-beam/bin/transformers-cli @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from transformers.commands.transformers_cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/uvicorn b/.venv-beam/bin/uvicorn new file mode 100755 index 0000000..a38add8 --- /dev/null +++ b/.venv-beam/bin/uvicorn @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from uvicorn.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/watchmedo b/.venv-beam/bin/watchmedo new file mode 100755 index 0000000..edb68e0 --- /dev/null +++ b/.venv-beam/bin/watchmedo @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from watchdog.watchmedo import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/bin/wsdump b/.venv-beam/bin/wsdump new file mode 100755 index 0000000..c79c37f --- /dev/null +++ b/.venv-beam/bin/wsdump @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from websocket._wsdump import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-beam/pyvenv.cfg b/.venv-beam/pyvenv.cfg new file mode 100644 index 0000000..1f0ae2f --- /dev/null +++ b/.venv-beam/pyvenv.cfg @@ -0,0 +1,3 @@ +home = /Users/luisomoreau/.pyenv/versions/3.10.13/bin +include-system-site-packages = false +version = 3.10.13 diff --git a/.venv-ei/bin/Activate.ps1 b/.venv-ei/bin/Activate.ps1 new file mode 100644 index 0000000..b49d77b --- /dev/null +++ b/.venv-ei/bin/Activate.ps1 @@ -0,0 +1,247 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/.venv-ei/bin/activate b/.venv-ei/bin/activate new file mode 100644 index 0000000..6243e54 --- /dev/null +++ b/.venv-ei/bin/activate @@ -0,0 +1,69 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null + fi + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-ei" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1="(.venv-ei) ${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT="(.venv-ei) " + export VIRTUAL_ENV_PROMPT +fi + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null +fi diff --git a/.venv-ei/bin/activate.csh b/.venv-ei/bin/activate.csh new file mode 100644 index 0000000..73b3134 --- /dev/null +++ b/.venv-ei/bin/activate.csh @@ -0,0 +1,26 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-ei" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = "(.venv-ei) $prompt" + setenv VIRTUAL_ENV_PROMPT "(.venv-ei) " +endif + +alias pydoc python -m pydoc + +rehash diff --git a/.venv-ei/bin/activate.fish b/.venv-ei/bin/activate.fish new file mode 100644 index 0000000..a865363 --- /dev/null +++ b/.venv-ei/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/); you cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + set -e _OLD_FISH_PROMPT_OVERRIDE + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + end + + set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV "/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-ei" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# Unset PYTHONHOME if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # Save the current fish_prompt function as the function _old_fish_prompt. + functions -c fish_prompt _old_fish_prompt + + # With the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command. + set -l old_status $status + + # Output the venv prompt; color taken from the blue of the Python logo. + printf "%s%s%s" (set_color 4B8BBE) "(.venv-ei) " (set_color normal) + + # Restore the return status of the previous command. + echo "exit $old_status" | . + # Output the original/"old" prompt. + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" + set -gx VIRTUAL_ENV_PROMPT "(.venv-ei) " +end diff --git a/.venv-ei/bin/f2py b/.venv-ei/bin/f2py new file mode 100755 index 0000000..ffd3537 --- /dev/null +++ b/.venv-ei/bin/f2py @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-ei/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from numpy.f2py.f2py2e import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-ei/bin/f2py3 b/.venv-ei/bin/f2py3 new file mode 100755 index 0000000..ffd3537 --- /dev/null +++ b/.venv-ei/bin/f2py3 @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-ei/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from numpy.f2py.f2py2e import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-ei/bin/f2py3.10 b/.venv-ei/bin/f2py3.10 new file mode 100755 index 0000000..ffd3537 --- /dev/null +++ b/.venv-ei/bin/f2py3.10 @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-ei/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from numpy.f2py.f2py2e import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-ei/bin/normalizer b/.venv-ei/bin/normalizer new file mode 100755 index 0000000..10226dd --- /dev/null +++ b/.venv-ei/bin/normalizer @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-ei/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from charset_normalizer.cli import cli_detect +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(cli_detect()) diff --git a/.venv-ei/bin/pip b/.venv-ei/bin/pip new file mode 100755 index 0000000..419e35a --- /dev/null +++ b/.venv-ei/bin/pip @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-ei/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-ei/bin/pip3 b/.venv-ei/bin/pip3 new file mode 100755 index 0000000..419e35a --- /dev/null +++ b/.venv-ei/bin/pip3 @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-ei/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-ei/bin/pip3.10 b/.venv-ei/bin/pip3.10 new file mode 100755 index 0000000..419e35a --- /dev/null +++ b/.venv-ei/bin/pip3.10 @@ -0,0 +1,8 @@ +#!/Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-ei/bin/python3.10 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv-ei/pyvenv.cfg b/.venv-ei/pyvenv.cfg new file mode 100644 index 0000000..42fef29 --- /dev/null +++ b/.venv-ei/pyvenv.cfg @@ -0,0 +1,3 @@ +home = /Users/luisomoreau/workspace/ei/ai-labeling-audio-spectrogram-transformer/.venv-beam/bin +include-system-site-packages = false +version = 3.10.13 diff --git a/Dockerfile b/Dockerfile index c64f84c..3263f94 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,9 @@ -FROM ubuntu:20.04 +FROM python:3.10.12 WORKDIR /app -RUN apt update && apt install -y python3 python3-distutils wget ffmpeg -RUN wget https://bootstrap.pypa.io/get-pip.py && \ - python3.8 get-pip.py "pip==21.3.1" && \ - rm get-pip.py - -# Python dependencies COPY requirements.txt ./ -RUN pip3 --no-cache-dir install -r requirements.txt +RUN pip3 install -r requirements.txt COPY . ./ diff --git a/README.md b/README.md index f46b93f..2034b1e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# AI Actions block: Audio Spectrogram Transformers labeling block (HuggingFace) +# AI labeling block: Audio Spectrogram Transformers labeling block (HuggingFace) -This is an Edge Impulse [AI Actions block](https://docs.edgeimpulse.com/docs/edge-impulse-studio/organizations/custom-blocks/transformation-blocks) that uses [Audio Spectrogram Transformers](https://huggingface.co/docs/transformers/en/model_doc/audio-spectrogram-transformer) from HuggingFace to automatically label audio data. You can use this repo as the basis for custom tasks that use big ML models to help with labeling or data quality tasks in your project. +This is an Edge Impulse [AI labeling block](https://docs.edgeimpulse.com/studio/organizations/custom-blocks/custom-ai-labeling-blocks) that uses [Audio Spectrogram Transformers](https://huggingface.co/docs/transformers/en/model_doc/audio-spectrogram-transformer) from HuggingFace to automatically label audio data. You can use this repo as the basis for custom tasks that use big ML models to help with labeling or data quality tasks in your project. ## Use this from Edge Impulse (professional / enterprise) @@ -10,7 +10,43 @@ If you just want to use this block as a labeling tool in your Edge Impulse proje You can use this repository as a basis to integrate any model that's deployed using HuggingFace's Serverless Inference API. The model we're using here is [MIT/ast-finetuned-audioset-10-10-0.4593](https://huggingface.co/MIT/ast-finetuned-audioset-10-10-0.4593), but it should be easy to adapt this repository to any other model. If your desired HuggingFace model is not available through HuggingFace's APIs, see [zero-shot-object-detector-labeling-block](https://github.com/edgeimpulse/zero-shot-object-detector-labeling-block) for information on how to deploy models using Beam.cloud. -### 1. Running this block locally +### Host the Hugging Face model to Beam.cloud + +### 1. Deploying the inference server + +1. Sign up for an account at [Beam.cloud](https://www.beam.cloud). +2. The Beam inference server (it's very simple) is implemented in [beam_inference_server.py](beam_inference_server.py). If you want to use a different HuggingFace model you can swap it out there. + + > You might want to lower `keep_warm_seconds` to keep cost under control. Currently the server will stay alive for 10 minutes after the last request. + +3. Use Python 3.10: + + ```bash + pyenv install 3.10.13 + pyenv local 3.10.13 + ``` + +4. Install the Beam Python dependencies, and deploy: + + ```bash + python3 -m venv .venv-beam + source .venv-beam/bin/activate + pip3 install -r requirements-beam.txt + + beam deploy beam_app.py:classify_audio + ``` + +4. From the output of the `beam deploy` command, parse the endpoint, and your access key: + + ```bash + curl -X POST 'https://audio-spectrogram-transformer-XXXX-v2.app.beam.cloud' \ + -H 'Connection: keep-alive' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer co9SiXXX...==' \ + -d '{}' + ``` + +### Running this block locally 1. Create a new Edge Impulse project, and add some unlabeled audio, e.g. with some speech. @@ -28,26 +64,27 @@ You can use this repository as a basis to integrate any model that's deployed us [1299267659, 1299267609, 1299267606] ``` -3. Load your Edge Impulse API key, and your HuggingFace API Key: +3. Install the Python dependencies: ``` - export EI_PROJECT_API_KEY=ei_44... - export HF_API_KEY=hf_ng... + python3 -m venv .venv-ei + source .venv-ei/bin/activate + pip3 install -r requirements.txt ``` - > You can find your Edge Impulse API Key via **Dashboard > Keys**. You can find your HuggingFace API Key via [Access tokens](https://huggingface.co/settings/tokens) in your HuggingFace profile. - -4. Install the Python dependencies: +4. Load your Edge Impulse API key, and your HuggingFace API Key: ``` - python3 -m venv .venv - source .venv/bin/activate - pip3 install -r requirements.txt + export EI_PROJECT_API_KEY=ei_44... + export BEAM_ENDPOINT= https://....app.beam.cloud + export BEAM_ACCESS_KEY=o9SiEXK... ``` + > You can find your Edge Impulse API Key via **Dashboard > Keys**. You can find your HuggingFace API Key via [Access tokens](https://huggingface.co/settings/tokens) in your HuggingFace profile. + 5. Run `transform.py` to label your data: - ``` + ```bash python3 -u transform.py \ --audioset-labels "speech, music" \ --win-size-ms 1000 \ diff --git a/beam_app.py b/beam_app.py new file mode 100644 index 0000000..022a97f --- /dev/null +++ b/beam_app.py @@ -0,0 +1,66 @@ +import os +import numpy as np +from beam import endpoint, Image, Volume, QueueDepthAutoscaler +from transformers import pipeline +from pydub import AudioSegment +import io +import base64 + +# Set up Hugging Face cache directory +HF_HOME_DIR = './checkpoints' +CACHE_DIR = './checkpoints/cache' +os.environ['HF_HOME'] = HF_HOME_DIR + +# Define the model loading function +def load_model(): + model = pipeline( + model="MIT/ast-finetuned-audioset-10-10-0.4593", + task="audio-classification", + device="cuda:0", + cache_dir=CACHE_DIR, + ) + return model + +# Configure autoscaling +autoscaling_config = QueueDepthAutoscaler( + max_containers=5, + tasks_per_container=30, +) + +# Define the Beam endpoint +@endpoint( + name="audio-spectrogram-transformer", + cpu=2, + memory="8Gi", + gpu=["RTX4090"], # or ["T4", "RTX4090"] if you want to allow multiple GPU types + image=Image( + python_version="python3.10", + python_packages=[ + "transformers==4.45.2", + "torch==2.5.0", + "pydub==0.25.1", + "soundfile==0.12.1", + "numpy==1.24.0", + ], + ), + volumes=[ + Volume(name="audio-checkpoints", mount_path=HF_HOME_DIR), + ], + on_start=load_model, + keep_warm_seconds=300, + autoscaler=autoscaling_config, +) +def classify_audio(context, base64_audio: str, labels: list[str]): + model = context.on_start_value + audio_bytes = base64.b64decode(base64_audio) + audio = AudioSegment.from_file(io.BytesIO(audio_bytes), format="wav") + + # Convert AudioSegment to NumPy array + samples = np.array(audio.get_array_of_samples()) + if audio.channels > 1: + # If stereo, convert to mono by averaging channels + samples = samples.reshape((-1, audio.channels)).mean(axis=1) + + # Run inference + predictions = model(samples, top_k=10) + return {"predictions": predictions} diff --git a/parameters.json b/parameters.json index 583c82e..527e002 100644 --- a/parameters.json +++ b/parameters.json @@ -4,18 +4,15 @@ "info": { "name": "Audio labeling with AudioSet", "description": "Label any audio samples (multiple labels per sample) using a model trained on AudioSet. Make sure you only use AudioSet labels (https://research.google.com/audioset/dataset/index.html). You can relabel by adding the new label in parenthesis (e.g. \"Female speech, woman speaking (speaking)\").", + "requiredEnvVariables": [ + "BEAM_ENDPOINT", + "BEAM_ACCESS_KEY" + ], "operatesOn": [ "audio" ] }, "parameters": [ - { - "name": "Hugging Face API Key", - "value": "", - "type": "secret", - "help": "An API Key that gives access to Hugging Face", - "param": "HF_API_KEY" - }, { "name": "Labels of interest", "value": "speech\nmusic", diff --git a/requirements-beam.txt b/requirements-beam.txt new file mode 100644 index 0000000..ae61e3b --- /dev/null +++ b/requirements-beam.txt @@ -0,0 +1,4 @@ +transformers==4.45.2 +beam-client==0.2.189 +pydub==0.25.1 +numpy==1.24.0 diff --git a/requirements.txt b/requirements.txt index 494e171..dc5e87f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ numpy==1.24.4 pandas==2.0.3 pyarrow==12.0.1 -requests==2.28.2 +requests==2.32.2 ffmpeg==1.4.0 pydub==0.25.1 -edgeimpulse-api==1.61.3 +edgeimpulse-api==1.76.3 \ No newline at end of file diff --git a/transform.py b/transform.py index 084c27a..6e982a3 100644 --- a/transform.py +++ b/transform.py @@ -1,10 +1,11 @@ -import os, sys +import os +import sys import requests import time import argparse import json import math - +import base64 # Import the API objects we plan to use from edgeimpulse_api import ApiClient, Configuration, ProjectsApi, RawDataApi from edgeimpulse_api.models.set_sample_structured_labels_request import ( @@ -13,47 +14,35 @@ from edgeimpulse_api.models.edit_sample_label_request import ( EditSampleLabelRequest, ) - # For splitting audio from pydub import AudioSegment # Set and retrieve env. variables -if not os.getenv("HF_API_KEY"): - print("Missing HF_API_KEY") - sys.exit(1) - -## Property of the project if not os.getenv("EI_PROJECT_API_KEY"): print("Missing EI_PROJECT_API_KEY") sys.exit(1) - -HF_API_KEY = os.environ.get("HF_API_KEY") +if not os.getenv("BEAM_ENDPOINT"): + print("Missing BEAM_ENDPOINT") + sys.exit(1) +if not os.getenv("BEAM_ACCESS_KEY"): + print("Missing BEAM_ACCESS_KEY") + sys.exit(1) EI_PROJECT_API_KEY = os.environ.get("EI_PROJECT_API_KEY") EI_API_ENDPOINT = os.environ.get("EI_API_ENDPOINT", "https://studio.edgeimpulse.com/v1") - -# Inferencing of audio classifier -HF_INFERENCE_URL = "https://api-inference.huggingface.co/models/MIT/ast-finetuned-audioset-10-10-0.4593" - -# Settings +BEAM_ENDPOINT = os.environ.get("BEAM_ENDPOINT") +BEAM_ACCESS_KEY = os.environ.get("BEAM_ACCESS_KEY") OUTPUT_PATH = "./out" # Argument parser for command line arguments - parser = argparse.ArgumentParser( - description="Use Hugging Face to classify sound sample in your dataset" + description="Use Beam.cloud to classify sound samples in your dataset" ) -# parser.add_argument( -# "--in-file", -# type=str, -# required=False, -# help="Argument passed by Edge Impulse transformation block when the --in-file option is selected", -# ) parser.add_argument( "--audioset-labels", type=str, required=True, - help='Comma separated list of labels from "AudioSet" that will be be used to label the sample. When model returns any other label, the label for this sample in Edge Impulse will be set to "other".', + help='Comma-separated list of labels from "AudioSet" that will be used to label the sample.', ) parser.add_argument( "--win-size-ms", @@ -75,41 +64,33 @@ help='File with IDs (as JSON)') parser.add_argument("--propose-actions", type=int, required=False, help='If this flag is passed in, only propose suggested actions') - args, unknown = parser.parse_known_args() dir_path = os.path.dirname(os.path.realpath(__file__)) with open(os.path.join(dir_path, 'labels.txt'), 'r') as f: - valid_labels = [ x.strip().lower() for x in f.read().split("\n") ] + valid_labels = [x.strip().lower() for x in f.read().split("\n")] -# the replacement looks weird; but if calling this from CLI like "--prompt 'test\nanother line'" we'll get this still escaped -# (you could use $'test\nanotherline' but we won't do that in the Edge Impulse backend) audioset_labels = args.audioset_labels.replace('\\n', '\n') - audioset_labels_list = {} -for audioset_label in [ x.strip().lower() for x in audioset_labels.strip().split("\n") ]: - # 100% match with a valid label? OK +for audioset_label in [x.strip().lower() for x in audioset_labels.strip().split("\n")]: if audioset_label in valid_labels: audioset_labels_list[audioset_label] = audioset_label continue - if '(' in audioset_label and ')' in audioset_label: remapped_label = audioset_label[audioset_label.rindex('(') + 1:audioset_label.rindex(')')] filtered_label = audioset_label[0:audioset_label.rindex('(')].strip() if filtered_label in valid_labels: audioset_labels_list[filtered_label] = remapped_label continue - - # not found print('Valid labels: ' + ', '.join(valid_labels)) print('') print('Invalid label: "' + audioset_label + '" (see above for list of valid labels)') exit(1) -audioset_labels_list_str = ', '.join([ (k if audioset_labels_list[k] == k else k + ' (' + audioset_labels_list[k] + ')') for k in audioset_labels_list.keys() ]) - +audioset_labels_list_str = ', '.join([(k if audioset_labels_list[k] == k else k + ' (' + audioset_labels_list[k] + ')') for k in audioset_labels_list.keys()]) win_size_ms = args.win_size_ms win_stride_ms = args.win_stride_ms + if args.data_ids_file: with open(args.data_ids_file, 'r') as f: data_ids = json.load(f) @@ -128,29 +109,28 @@ print(' Min. confidence:', min_confidence) print(f" Window size: {win_size_ms}ms.") print(f" Window stride: {win_stride_ms}ms.") -if (len(data_ids) < 6): - print(' IDs:', ', '.join([ str(x) for x in data_ids ])) +if len(data_ids) < 6: + print(' IDs:', ', '.join([str(x) for x in data_ids])) else: - print(' IDs:', ', '.join([ str(x) for x in data_ids[0:5] ]), 'and ' + str(len(data_ids) - 5) + ' others') - + print(' IDs:', ', '.join([str(x) for x in data_ids[0:5]]), 'and ' + str(len(data_ids) - 5) + ' others') print('') -def classify_audio_sample(filename: str, hf_api_key: str): - headers = {"Authorization": f"Bearer {hf_api_key}"} - +# NEW: Function to call Beam.cloud endpoint +def classify_audio_sample(filename: str, beam_endpoint: str, beam_access_key: str, labels: list[str]): with open(filename, "rb") as f: - data = f.read() - response = requests.post(HF_INFERENCE_URL, headers=headers, data=data) - body = response.json() - - if (type(body) is dict and 'estimated_time' in body.keys()): - print('Request failed, model is spinning up:' + body['error'] + ', sleeping for ' + str(body['estimated_time'] + 5) + ' seconds...') - time.sleep(body['estimated_time'] + 5) - response = requests.post(HF_INFERENCE_URL, headers=headers, data=data) - body = response.json() - - return body - + base64_audio = base64.b64encode(f.read()).decode("utf-8") + body = json.dumps({ + "base64_audio": base64_audio, + "labels": list(audioset_labels_list.keys()), + }) + headers = { + "Authorization": f"Bearer {beam_access_key}", + "Content-Type": "application/json", + } + response = requests.post(beam_endpoint, headers=headers, data=body) + if response.status_code != 200: + raise Exception(f"Failed to classify audio: {response.text}") + return response.json()["predictions"] def ms_to_index(ms: float, total_values: int, total_ms: float): return int((ms / total_ms) * total_values) @@ -160,174 +140,103 @@ def create_splits_and_classify_from_wav( output_directory: str, win_size_ms: int, stride_ms: int, - hf_api_key: str, + beam_endpoint: str, + beam_access_key: str, audio_freq: float, values_count: int, ): - """ - Split the input audio file into windows of size "win_size_ms" with stride "stride_ms" - Then put each split though audio classifier and rename the file with the label - If the multilabel_output is enabled, return a structured multilabel list and files list - """ - - # Load the input audio file audio = AudioSegment.from_wav(input_file_path) audio_len = len(audio) - win_size_index = math.ceil(float(win_size_ms) * (audio_freq / 1000)) stride_index = math.ceil(float(stride_ms) * (audio_freq / 1000)) - print(f", length={audio_len}ms:") - - # File name all until file extension, preserve other dots in file name fname = input_file_path.split("/")[-1].split(".")[:-1] fname = ".".join(fname) - output_subdirectory = f"{output_directory}/{fname}" - if not os.path.exists(output_directory): os.makedirs(output_directory) if not os.path.exists(output_subdirectory): os.makedirs(output_subdirectory) - - intervals_list = ( - [] - ) - - # if 0 is specified we give one label per sample and send the whole sample to classify for a model - # THis means the loop will execute only once and one interval will be added to the list + intervals_list = [] if win_size_index == 0: win_size_index = values_count - windows = [] for i in range(0, values_count - win_size_index + 1, stride_index): start = i end = i + win_size_index if end > values_count: end = values_count - windows.append([ start, end ]) - - windows.append([ values_count - win_size_index, values_count ]) - - # print('audio_len', audio_len) - # print('values_count', values_count) - # print('windows', windows) - - # Get sliding window of size "win_size_ms" with stride "stride_ms" from audio wav - for [ start_index, end_index ] in windows: + windows.append([start, end]) + windows.append([values_count - win_size_index, values_count]) + for [start_index, end_index] in windows: start_ms = math.floor(float(start_index) / ((audio_freq / 1000))) end_ms = math.ceil(float(end_index) / ((audio_freq / 1000))) print(' [' + str(start_ms) + ' - ' + str(end_ms) + 'ms.] ', end='') - - # Get the split audio split_audio = audio[start_ms:end_ms] - # create a filename for split to identify by section fname_split = f"{fname}_{start_ms}_{end_ms}.wav" output_file = os.path.join(output_subdirectory, fname_split) - split_audio.export(output_file, format="wav") - # do inference - classification = classify_audio_sample(output_file, hf_api_key) - - if (not isinstance(classification, (list))): - print('classify_audio_sample did not return a list:', classification) + # Call Beam.cloud endpoint + classification = classify_audio_sample(output_file, beam_endpoint, beam_access_key, list(audioset_labels_list.keys())) + if not isinstance(classification, list): + print('Beam endpoint did not return a list:', classification) exit(1) - - if (len(classification) == 0): - print('classify_audio_sample did not return any classifications:', classification) + if len(classification) == 0: + print('Beam endpoint did not return any classifications:', classification) exit(1) - - if (not 'score' in classification[0].keys()): - print('classify_audio_sample did not return a classification with "score" in it:', classification) + if 'score' not in classification[0]: + print('Beam endpoint did not return a classification with "score" in it:', classification) exit(1) - top_n_labels_count = min(3, len(classification)) - top_n_labels_str = ', '.join([ f'{x["label"].lower()} ({float("{:.3f}".format(x["score"]))})' for x in classification[0:top_n_labels_count] ]) + top_n_labels_str = ', '.join([f'{x["label"].lower()} ({float("{:.3f}".format(x["score"]))})' for x in classification[0:top_n_labels_count]]) print(f'top results: {top_n_labels_str}', end='') - - # loop through classification list (sorted by score already) - # and find the first one in the audioset_labels_list and see if we're >= min confidence label = other_label for c in classification: - if (c['label'].lower() in audioset_labels_list.keys()): - if (c['score'] >= min_confidence): + if c['label'].lower() in audioset_labels_list.keys(): + if c['score'] >= min_confidence: label = audioset_labels_list[c['label'].lower()] break - print(f': result={label}') - - # Add label and interval tuple to split list multilabel_entry = (label, start_index, end_index) intervals_list.append(multilabel_entry) - return intervals_list - -def set_sample_label_in_studio( - api: RawDataApi, project_id: int, sample_id: int, label: str -): +def set_sample_label_in_studio(api: RawDataApi, project_id: int, sample_id: int, label: str): label_dict = {"label": label} set_sample_label_request = EditSampleLabelRequest.from_dict(label_dict) rc = api.edit_label(project_id, sample_id, set_sample_label_request) - return rc - -def append_multilabel_to_sample_in_studio( - api: RawDataApi, project_id: int, sample_id: int, structured_labels: str -): - set_sample_structured_labels_request = SetSampleStructuredLabelsRequest.from_json( - structured_labels - ) - # print(set_sample_structured_labels_request) - rc = api.set_sample_structured_labels( - project_id, sample_id, set_sample_structured_labels_request - ) - +def append_multilabel_to_sample_in_studio(api: RawDataApi, project_id: int, sample_id: int, structured_labels: str): + set_sample_structured_labels_request = SetSampleStructuredLabelsRequest.from_json(structured_labels) + rc = api.set_sample_structured_labels(project_id, sample_id, set_sample_structured_labels_request) return rc def get_sample_wav_from_project_by_id(project_id, sample_id, path): - # returns string - response = raw_data_api.get_sample_as_audio( - project_id=project_id, sample_id=sample_id, axis_ix=0, _preload_content=False - ) - # Save binary string as a WAV file - with open(path, "wb") as f: + response = raw_data_api.get_sample_as_audio(project_id=project_id, sample_id=sample_id, axis_ix=0, _preload_content=False) + # Create the 'input' directory if it doesn't exist + os.makedirs("input", exist_ok=True) + # Save the file in the 'input' folder + input_path = os.path.join("input", f"{sample.filename}.wav") + with open(input_path, "wb") as f: f.write(response.data) - # print(response) - # return 'output.wav' - + return input_path ##################### ### Begin entry point ##################### - -# Create top-level API client -config = Configuration( - host=EI_API_ENDPOINT, api_key={"ApiKeyAuthentication": EI_PROJECT_API_KEY} -) +config = Configuration(host=EI_API_ENDPOINT, api_key={"ApiKeyAuthentication": EI_PROJECT_API_KEY}) client = ApiClient(config) - -# Instantiate sub-clients projects_api = ProjectsApi(client) raw_data_api = RawDataApi(client) - project_id = None -# Get the project ID, which we'll need for future API calls -response = ( - projects_api.list_projects() -) # BC we have PI key it will list only this project +response = projects_api.list_projects() if not hasattr(response, "success") or getattr(response, "success") == False: raise RuntimeError("Could not obtain the project ID.") else: project_id = response.projects[0].id - -# Print the project ID print(f"Project ID: {project_id}") -# Get relevant project info -project_info = projects_api.get_project_info(project_id=project_id).to_dict() - def current_ms(): return round(time.time() * 1000) @@ -335,55 +244,39 @@ def current_ms(): for data_id in data_ids: ix = ix + 1 now = current_ms() - sample = (raw_data_api.get_sample(project_id=project_id, sample_id=data_id, proposed_actions_job_id=args.propose_actions)).sample - prefix = '[' + str(ix).rjust(len(str(len(data_ids))), ' ') + '/' + str(len(data_ids)) + ']' - print(prefix, 'Labeling ' + sample.filename + ' (ID ' + str(sample.id) + ')', end='') - - # # Skip sample if it already has structured labels - # if not "structuredLabels" in sample: - # print(f"Skipping sample {sample_id} as it already has structured labels") - # continue - - total_length_ms = sample.total_length_ms # length in Ms - values_count = sample.values_count # length in indices - - # Get the audio file from the project (from the API) - sample_file_path = f"./{sample.filename}.wav" - sample_data = get_sample_wav_from_project_by_id( - project_id, sample.id, sample_file_path - ) - - # Create splits and classify + total_length_ms = sample.total_length_ms + values_count = sample.values_count + sample_file_path = os.path.join("input", f"{sample.filename}.wav") + sample_data = get_sample_wav_from_project_by_id(project_id, sample.id, sample_file_path) intervals_list = create_splits_and_classify_from_wav( sample_file_path, OUTPUT_PATH, win_size_ms, win_stride_ms, - HF_API_KEY, + BEAM_ENDPOINT, + BEAM_ACCESS_KEY, sample.frequency, values_count ) - max_ix = values_count - 1 structured_labels = [] last_index = 0 for interval in intervals_list: label, start_ix, end_ix = interval - if (end_ix > max_ix): end_ix = max_ix + if end_ix > max_ix: + end_ix = max_ix structured_labels.append({ 'startIndex': start_ix, 'endIndex': end_ix, 'label': label }) last_index = end_ix + 1 - - new_metadata = sample.metadata if sample.metadata else { } - new_metadata['labeled_by'] = 'audio-spectrogram-transformer' + new_metadata = sample.metadata if sample.metadata else {} + new_metadata['labeled_by'] = 'audio-spectrogram-transformer-beam' new_metadata['ast_labels'] = audioset_labels_list_str - if args.propose_actions: raw_data_api.set_sample_proposed_changes(project_id=project_id, sample_id=sample.id, set_sample_proposed_changes_request={ 'jobId': args.propose_actions, @@ -393,7 +286,6 @@ def current_ms(): } }) else: - # print(set_sample_structured_labels_request) raw_data_api.set_sample_structured_labels( project_id, sample.id, set_sample_structured_labels_request={ 'structuredLabels': structured_labels @@ -402,5 +294,4 @@ def current_ms(): raw_data_api.set_sample_metadata(project_id=project_id, sample_id=sample.id, set_sample_metadata_request={ 'metadata': new_metadata }) - print('All done!')