Working single-file binary build
This commit is contained in:
parent
5a972ea0c6
commit
b1d75d7ff6
16 changed files with 202 additions and 78 deletions
|
|
@ -1,5 +1,7 @@
|
||||||
*
|
*
|
||||||
!LICENSE
|
!LICENSE
|
||||||
|
!install.sh
|
||||||
|
!pyinstaller/*.py
|
||||||
|
|
||||||
# opentts-abc
|
# opentts-abc
|
||||||
!opentts-abc/setup.py
|
!opentts-abc/setup.py
|
||||||
|
|
@ -14,6 +16,7 @@
|
||||||
!mimic3-tts/MANIFEST.in
|
!mimic3-tts/MANIFEST.in
|
||||||
!mimic3-tts/requirements.txt
|
!mimic3-tts/requirements.txt
|
||||||
!mimic3-tts/mimic3_tts/*.py
|
!mimic3-tts/mimic3_tts/*.py
|
||||||
|
!mimic3-tts/mimic3_tts/voices.json
|
||||||
!mimic3-tts/mimic3_tts/VERSION
|
!mimic3-tts/mimic3_tts/VERSION
|
||||||
|
|
||||||
# HTTP server
|
# HTTP server
|
||||||
|
|
|
||||||
15
Dockerfile
15
Dockerfile
|
|
@ -38,22 +38,13 @@ RUN --mount=type=cache,id=apt-build,target=/var/cache/apt \
|
||||||
python3 python3-pip python3-venv \
|
python3 python3-pip python3-venv \
|
||||||
build-essential python3-dev
|
build-essential python3-dev
|
||||||
|
|
||||||
RUN mkdir -p /home/mimic3/app
|
|
||||||
WORKDIR /home/mimic3/app
|
WORKDIR /home/mimic3/app
|
||||||
|
|
||||||
# Create virtual environment
|
COPY ./ ./
|
||||||
RUN --mount=type=cache,id=pip-venv,target=/root/.cache/pip \
|
|
||||||
python3 -m venv .venv && \
|
|
||||||
.venv/bin/pip3 install --upgrade pip && \
|
|
||||||
.venv/bin/pip3 install --upgrade wheel setuptools
|
|
||||||
|
|
||||||
COPY ./ /home/mimic3/app/
|
# Install mimic3
|
||||||
|
|
||||||
# Install packages in order
|
|
||||||
RUN --mount=type=cache,id=pip-requirements,target=/root/.cache/pip \
|
RUN --mount=type=cache,id=pip-requirements,target=/root/.cache/pip \
|
||||||
.venv/bin/pip3 install -e opentts-abc && \
|
./install.sh
|
||||||
.venv/bin/pip3 install -e mimic3-tts && \
|
|
||||||
.venv/bin/pip3 install -e mimic3-http
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
116
Dockerfile.binary
Normal file
116
Dockerfile.binary
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
# Copyright 2022 Mycroft AI Inc.
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Dockerfile for Mimic 3 (https://github.com/MycroftAI/mimic3)
|
||||||
|
#
|
||||||
|
# Creates self-contained binaries using PyInstaller
|
||||||
|
# (https://pyinstaller.readthedocs.io/en/stable/).
|
||||||
|
#
|
||||||
|
# Requires Docker buildx: https://docs.docker.com/buildx/working-with-buildx/
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FROM debian:bullseye as build
|
||||||
|
ARG TARGETARCH
|
||||||
|
ARG TARGETVARIANT
|
||||||
|
|
||||||
|
ENV LANG C.UTF-8
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN echo "Dir::Cache var/cache/apt/${TARGETARCH}${TARGETVARIANT};" > /etc/apt/apt.conf.d/01cache
|
||||||
|
|
||||||
|
RUN --mount=type=cache,id=apt-build,target=/var/cache/apt \
|
||||||
|
mkdir -p /var/cache/apt/${TARGETARCH}${TARGETVARIANT}/archives/partial && \
|
||||||
|
apt-get update && \
|
||||||
|
apt-get install --yes --no-install-recommends \
|
||||||
|
python3 python3-pip python3-venv \
|
||||||
|
build-essential python3-dev \
|
||||||
|
libespeak-ng1
|
||||||
|
|
||||||
|
WORKDIR /build/mimic3
|
||||||
|
COPY ./ ./
|
||||||
|
|
||||||
|
# Install mimic3
|
||||||
|
RUN --mount=type=cache,id=pip-venv,target=/root/.cache/pip \
|
||||||
|
./install.sh
|
||||||
|
|
||||||
|
# Install PyInstaller
|
||||||
|
RUN --mount=type=cache,id=pip-venv,target=/root/.cache/pip \
|
||||||
|
.venv/bin/pip3 install 'pyinstaller>=4,<5'
|
||||||
|
|
||||||
|
# Create binary for command-line interface
|
||||||
|
RUN .venv/bin/pyinstaller \
|
||||||
|
--onefile \
|
||||||
|
--noconfirm \
|
||||||
|
--name mimic3 \
|
||||||
|
--hidden-import 'pycrfsuite._dumpparser' \
|
||||||
|
--hidden-import 'pycrfsuite._logparser' \
|
||||||
|
--collect-binaries 'onnxruntime' \
|
||||||
|
--add-binary "$(/sbin/ldconfig -p | grep libespeak-ng.so.1 | awk '{print $4}'):." \
|
||||||
|
--collect-data 'gruut' \
|
||||||
|
--hidden-import "gruut_lang_de" \
|
||||||
|
--collect-data "gruut_lang_de" \
|
||||||
|
--hidden-import "gruut_lang_en" \
|
||||||
|
--collect-data "gruut_lang_en" \
|
||||||
|
--hidden-import "gruut_lang_fr" \
|
||||||
|
--collect-data "gruut_lang_fr" \
|
||||||
|
--hidden-import "gruut_lang_it" \
|
||||||
|
--collect-data "gruut_lang_it" \
|
||||||
|
--hidden-import "gruut_lang_nl" \
|
||||||
|
--collect-data "gruut_lang_nl" \
|
||||||
|
--hidden-import "gruut_lang_ru" \
|
||||||
|
--collect-data "gruut_lang_ru" \
|
||||||
|
--hidden-import "gruut_lang_sw" \
|
||||||
|
--collect-data "gruut_lang_sw" \
|
||||||
|
--collect-data 'espeak_phonemizer' \
|
||||||
|
--collect-data 'phonemes2ids' \
|
||||||
|
--collect-data 'mimic3_tts' \
|
||||||
|
pyinstaller/mimic3.py
|
||||||
|
|
||||||
|
# Create binary for web server
|
||||||
|
RUN .venv/bin/pyinstaller \
|
||||||
|
--onefile \
|
||||||
|
--noconfirm \
|
||||||
|
--name mimic3-server \
|
||||||
|
--hidden-import 'pycrfsuite._dumpparser' \
|
||||||
|
--hidden-import 'pycrfsuite._logparser' \
|
||||||
|
--collect-binaries 'onnxruntime' \
|
||||||
|
--add-binary "$(/sbin/ldconfig -p | grep libespeak-ng.so.1 | awk '{print $4}'):." \
|
||||||
|
--collect-data 'gruut' \
|
||||||
|
--hidden-import "gruut_lang_de" \
|
||||||
|
--collect-data "gruut_lang_de" \
|
||||||
|
--hidden-import "gruut_lang_en" \
|
||||||
|
--collect-data "gruut_lang_en" \
|
||||||
|
--hidden-import "gruut_lang_fr" \
|
||||||
|
--collect-data "gruut_lang_fr" \
|
||||||
|
--hidden-import "gruut_lang_it" \
|
||||||
|
--collect-data "gruut_lang_it" \
|
||||||
|
--hidden-import "gruut_lang_nl" \
|
||||||
|
--collect-data "gruut_lang_nl" \
|
||||||
|
--hidden-import "gruut_lang_ru" \
|
||||||
|
--collect-data "gruut_lang_ru" \
|
||||||
|
--hidden-import "gruut_lang_sw" \
|
||||||
|
--collect-data "gruut_lang_sw" \
|
||||||
|
--collect-data 'espeak_phonemizer' \
|
||||||
|
--collect-data 'phonemes2ids' \
|
||||||
|
--collect-data 'mimic3_tts' \
|
||||||
|
--collect-data 'mimic3_http' \
|
||||||
|
pyinstaller/mimic3_server.py
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FROM scratch
|
||||||
|
|
||||||
|
COPY --from=build /build/mimic3/dist/ /
|
||||||
10
Makefile
10
Makefile
|
|
@ -13,7 +13,10 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
.PHONY: dist install docker
|
.PHONY: dist install docker binaries
|
||||||
|
|
||||||
|
SHELL := bash
|
||||||
|
DOCKER_PLATFORM := linux/amd64
|
||||||
|
|
||||||
dist:
|
dist:
|
||||||
cd opentts-abc && python3 setup.py sdist
|
cd opentts-abc && python3 setup.py sdist
|
||||||
|
|
@ -28,4 +31,7 @@ install:
|
||||||
./install.sh
|
./install.sh
|
||||||
|
|
||||||
docker:
|
docker:
|
||||||
docker buildx build . -f Dockerfile --tag mycroftai/mimic3 --load
|
docker buildx build . -f Dockerfile --platform $(DOCKER_PLATFORM) --tag mycroftai/mimic3 --load
|
||||||
|
|
||||||
|
binaries:
|
||||||
|
docker buildx build . -f Dockerfile.binary $(DOCKER_PLATFORM) --output type=local,dest=dist/$(DOCKER_PLATFORM)
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,11 @@ this_dir="$( cd "$( dirname "$0" )" && pwd )"
|
||||||
|
|
||||||
# Kebab to snake case
|
# Kebab to snake case
|
||||||
module_name="$(basename "${this_dir}" | sed -e 's/-/_/g')"
|
module_name="$(basename "${this_dir}" | sed -e 's/-/_/g')"
|
||||||
|
base_dir="$(realpath "${this_dir}/..")"
|
||||||
src_dir="${this_dir}/${module_name}"
|
src_dir="${this_dir}/${module_name}"
|
||||||
|
|
||||||
# Path to virtual environment
|
# Path to virtual environment
|
||||||
: "${venv:=${this_dir}/.venv}"
|
: "${venv:=${base_dir}/.venv}"
|
||||||
|
|
||||||
if [ -d "${venv}" ]; then
|
if [ -d "${venv}" ]; then
|
||||||
# Activate virtual environment if available
|
# Activate virtual environment if available
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,10 @@ import csv
|
||||||
import io
|
import io
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import shlex
|
||||||
|
import shutil
|
||||||
import string
|
import string
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import threading
|
import threading
|
||||||
|
|
@ -39,6 +42,7 @@ if typing.TYPE_CHECKING:
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(_PACKAGE)
|
_LOGGER = logging.getLogger(_PACKAGE)
|
||||||
|
|
||||||
|
_DEFAULT_PLAY_PROGRAMS = ["paplay", "play -q", "aplay -q"]
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -264,7 +268,7 @@ def process_result(state: CommandLineInterfaceState):
|
||||||
wav_bytes = result.to_wav_bytes()
|
wav_bytes = result.to_wav_bytes()
|
||||||
|
|
||||||
if wav_bytes:
|
if wav_bytes:
|
||||||
play_wav_bytes(wav_bytes)
|
play_wav_bytes(state.args, wav_bytes)
|
||||||
|
|
||||||
if args.output_dir:
|
if args.output_dir:
|
||||||
if not wav_bytes:
|
if not wav_bytes:
|
||||||
|
|
@ -387,7 +391,7 @@ def process_lines(state: CommandLineInterfaceState):
|
||||||
wav_file_play.setnchannels(state.num_channels)
|
wav_file_play.setnchannels(state.num_channels)
|
||||||
wav_file_play.writeframes(state.all_audio)
|
wav_file_play.writeframes(state.all_audio)
|
||||||
|
|
||||||
play_wav_bytes(wav_io.getvalue())
|
play_wav_bytes(state.args, wav_io.getvalue())
|
||||||
else:
|
else:
|
||||||
# Write output directly to stdout
|
# Write output directly to stdout
|
||||||
wav_file_write: wave.Wave_write = wave.open(sys.stdout.buffer, "wb")
|
wav_file_write: wave.Wave_write = wave.open(sys.stdout.buffer, "wb")
|
||||||
|
|
@ -406,15 +410,20 @@ def shutdown_tts(state: CommandLineInterfaceState):
|
||||||
state.tts = None
|
state.tts = None
|
||||||
|
|
||||||
|
|
||||||
def play_wav_bytes(wav_bytes: bytes):
|
def play_wav_bytes(args: argparse.Namespace, wav_bytes: bytes):
|
||||||
from playsound import playsound
|
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(mode="wb+", suffix=".wav") as wav_file:
|
with tempfile.NamedTemporaryFile(mode="wb+", suffix=".wav") as wav_file:
|
||||||
wav_file.write(wav_bytes)
|
wav_file.write(wav_bytes)
|
||||||
wav_file.seek(0)
|
wav_file.seek(0)
|
||||||
|
|
||||||
_LOGGER.debug("Playing WAV file: %s", wav_file.name)
|
for play_program in reversed(args.play_program):
|
||||||
playsound(wav_file.name)
|
play_cmd = shlex.split(play_program)
|
||||||
|
if not shutil.which(play_cmd[0]):
|
||||||
|
continue
|
||||||
|
|
||||||
|
play_cmd.append(wav_file.name)
|
||||||
|
_LOGGER.debug("Playing WAV file: %s", play_cmd)
|
||||||
|
subprocess.check_output(play_cmd)
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
def print_voices(state: CommandLineInterfaceState):
|
def print_voices(state: CommandLineInterfaceState):
|
||||||
|
|
@ -521,6 +530,12 @@ def get_args():
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--preload-voice", action="append", help="Preload voice when starting up"
|
"--preload-voice", action="append", help="Preload voice when starting up"
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--play-program",
|
||||||
|
action="append",
|
||||||
|
default=_DEFAULT_PLAY_PROGRAMS,
|
||||||
|
help="Program(s) used to play WAV files",
|
||||||
|
)
|
||||||
parser.add_argument("--seed", type=int, help="Set random seed (default: not set)")
|
parser.add_argument("--seed", type=int, help="Set random seed (default: not set)")
|
||||||
parser.add_argument("--version", action="store_true", help="Print version and exit")
|
parser.add_argument("--version", action="store_true", help="Print version and exit")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
|
|
||||||
|
|
@ -19,5 +19,7 @@ from xdgenvpy import XDG
|
||||||
|
|
||||||
DEFAULT_VOICE = "en_US/vctk_low"
|
DEFAULT_VOICE = "en_US/vctk_low"
|
||||||
DEFAULT_LANGUAGE = "en_US"
|
DEFAULT_LANGUAGE = "en_US"
|
||||||
DEFAULT_VOICES_URL_FORMAT = "https://github.com/MycroftAI/mimic3-voices/raw/master/voices/{lang}/{name}"
|
DEFAULT_VOICES_URL_FORMAT = (
|
||||||
|
"https://github.com/MycroftAI/mimic3-voices/raw/master/voices/{lang}/{name}"
|
||||||
|
)
|
||||||
DEFAULT_VOICES_DOWNLOAD_DIR = Path(XDG().XDG_DATA_HOME) / "mimic3" / "voices"
|
DEFAULT_VOICES_DOWNLOAD_DIR = Path(XDG().XDG_DATA_HOME) / "mimic3" / "voices"
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,6 @@ ignore_missing_imports = True
|
||||||
[mypy-onnxruntime.*]
|
[mypy-onnxruntime.*]
|
||||||
ignore_missing_imports = True
|
ignore_missing_imports = True
|
||||||
|
|
||||||
[mypy-playsound.*]
|
|
||||||
ignore_missing_imports = True
|
|
||||||
|
|
||||||
[mypy-tqdm.*]
|
[mypy-tqdm.*]
|
||||||
ignore_missing_imports = True
|
ignore_missing_imports = True
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
dataclasses-json<1.0
|
dataclasses-json<1.0
|
||||||
espeak-phonemizer>=1.0,<2.0
|
espeak-phonemizer>=1.0,<2.0
|
||||||
gruut>=2.2.2,<3.0
|
gruut>=2.3.0,<3.0
|
||||||
numpy<2.0
|
numpy<2.0
|
||||||
onnxruntime>=1.6,<2.0
|
onnxruntime>=1.6,<2.0
|
||||||
opentts_abc<1.0
|
opentts_abc<1.0
|
||||||
phonemes2ids<2.0
|
phonemes2ids<2.0
|
||||||
playsound~=1.3.0
|
|
||||||
tqdm>=4,<5
|
tqdm>=4,<5
|
||||||
xdgenvpy>2.0,<3
|
xdgenvpy>2.0,<3
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
black==22.1.0
|
|
||||||
coverage==5.0.4
|
|
||||||
flake8==3.7.9
|
|
||||||
mypy==0.910
|
|
||||||
pylint==2.10.2
|
|
||||||
pytest==5.4.1
|
|
||||||
pytest-cov==2.8.1
|
|
||||||
|
|
@ -81,7 +81,7 @@ setup(
|
||||||
author_email="michael.hansen@mycroft.ai",
|
author_email="michael.hansen@mycroft.ai",
|
||||||
license="AGPLv3+",
|
license="AGPLv3+",
|
||||||
packages=setuptools.find_packages(),
|
packages=setuptools.find_packages(),
|
||||||
package_data={"mimic3_tts": ["VERSION", "py.typed"]},
|
package_data={"mimic3_tts": ["VERSION", "py.typed", "voices.json"]},
|
||||||
install_requires=requirements,
|
install_requires=requirements,
|
||||||
extras_require={':python_version<"3.9"': ["importlib_resources"], **extras_require},
|
extras_require={':python_version<"3.9"': ["importlib_resources"], **extras_require},
|
||||||
entry_points={"console_scripts": ["mimic3 = mimic3_cli.__main__:main"]},
|
entry_points={"console_scripts": ["mimic3 = mimic3_cli.__main__:main"]},
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
set -eo pipefail
|
|
||||||
|
|
||||||
# Directory of *this* script
|
|
||||||
this_dir="$( cd "$( dirname "$0" )" && pwd )"
|
|
||||||
|
|
||||||
# Path to virtual environment
|
|
||||||
: "${venv:=${this_dir}/.venv}"
|
|
||||||
|
|
||||||
# Python binary to use
|
|
||||||
: "${PYTHON=python3}"
|
|
||||||
|
|
||||||
# pip install command
|
|
||||||
: "${PIP_INSTALL=install}"
|
|
||||||
|
|
||||||
python_version="$(${PYTHON} --version)"
|
|
||||||
|
|
||||||
# Create virtual environment
|
|
||||||
echo "Creating virtual environment at ${venv} (${python_version})"
|
|
||||||
rm -rf "${venv}"
|
|
||||||
"${PYTHON}" -m venv "${venv}"
|
|
||||||
source "${venv}/bin/activate"
|
|
||||||
|
|
||||||
# Install Python dependencies
|
|
||||||
echo 'Installing Python dependencies'
|
|
||||||
pip3 ${PIP_INSTALL} --upgrade pip
|
|
||||||
pip3 ${PIP_INSTALL} --upgrade wheel setuptools
|
|
||||||
|
|
||||||
find "${this_dir}" -name 'requirements*.txt' -type f -print0 | \
|
|
||||||
xargs -0 -n1 pip3 ${PIP_INSTALL} -r
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
echo "OK"
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
black==22.1.0
|
|
||||||
coverage==5.0.4
|
|
||||||
flake8==3.7.9
|
|
||||||
mypy==0.910
|
|
||||||
pylint==2.10.2
|
|
||||||
pytest==5.4.1
|
|
||||||
pytest-cov==2.8.1
|
|
||||||
21
pyinstaller/mimic3.py
Normal file
21
pyinstaller/mimic3.py
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# Copyright 2022 Mycroft AI Inc.
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
"""Stub for PyInstaller"""
|
||||||
|
|
||||||
|
from mimic3_tts.__main__ import main
|
||||||
|
|
||||||
|
main()
|
||||||
21
pyinstaller/mimic3_server.py
Normal file
21
pyinstaller/mimic3_server.py
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# Copyright 2022 Mycroft AI Inc.
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
"""Stub for PyInstaller"""
|
||||||
|
|
||||||
|
from mimic3_http.__main__ import main
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
black==22.1.0
|
black==22.3.0
|
||||||
coverage==5.0.4
|
coverage==5.0.4
|
||||||
flake8==3.7.9
|
flake8==3.7.9
|
||||||
mypy==0.910
|
mypy==0.910
|
||||||
Loading…
Add table
Add a link
Reference in a new issue