diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml new file mode 100644 index 0000000..5be5c45 --- /dev/null +++ b/.github/workflows/publish-package.yml @@ -0,0 +1,60 @@ +name: Publish package +# Publish to PyPI when new release on GitHub, if tests pass +on: + release: + types: [created] + workflow_dispatch: + # Manual trigger in case the release needs to be rerun + +jobs: + + # tests: + # runs-on: ubuntu-latest + # strategy: + # matrix: + # python-version: [3.6, 3.7, 3.8] + # steps: + # - uses: actions/checkout@v2 + # - name: Set up Python ${{ matrix.python-version }} + # uses: actions/setup-python@v2 + # with: + # python-version: ${{ matrix.python-version }} + # - name: Install dependencies + # run: | + # python -m pip install --upgrade pip + # pip install flake8 pytest + # if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + # - name: Lint with flake8 + # run: | + # # stop the build if there are Python syntax errors or undefined names + # flake8 . --count --exit-zero --select=E9,F63,F7,F82 --show-source --statistics + # # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + # flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + # - name: Test with pytest + # run: | + # python setup.py pytest + + + publish: + # needs: [ tests ] + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel twine + python setup.py sdist bdist_wheel + + - name: Build and publish to PyPI + env: + TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + run: | + python setup.py sdist bdist_wheel + twine upload dist/* diff --git a/README.md b/README.md index 170b1c4..388d06b 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ You can run your own API server in just a few lines of setup! Make sure you have installed Python (3.8 or higher), then simply issue: ```bash -git clone https://github.com/uav4geo/LibreTranslate --recurse-submodules +git clone https://github.com/uav4geo/LibreTranslate cd LibreTranslate pip install -r requirements.txt python main.py [args] diff --git a/app/__init.py__ b/app/__init.py__ new file mode 100644 index 0000000..e69de29 diff --git a/app/app.py b/app/app.py index 9b56f0d..1bf4ae2 100644 --- a/app/app.py +++ b/app/app.py @@ -3,6 +3,7 @@ from flask_swagger import swagger from flask_swagger_ui import get_swaggerui_blueprint from langdetect import detect_langs from langdetect import DetectorFactory +from pkg_resources import resource_filename DetectorFactory.seed = 0 # deterministic def get_remote_address(): @@ -67,7 +68,7 @@ def create_app(char_limit=-1, req_limit=-1, batch_limit=-1, ga_id=None, debug=Fa @app.route("/") def index(): - return render_template('index.html', gaId=ga_id, frontendTimeout=frontend_timeout) + return render_template(resource_filename('app', 'templates/index.html'), gaId=ga_id, frontendTimeout=frontend_timeout) @app.route("/languages") def langs(): diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..243ba07 --- /dev/null +++ b/app/main.py @@ -0,0 +1,46 @@ +import argparse +from app.app import create_app + +def main(): + parser = argparse.ArgumentParser(description='LibreTranslate - Free and Open Source Translation API') + parser.add_argument('--host', type=str, + help='Hostname (%(default)s)', default="127.0.0.1") + parser.add_argument('--port', type=int, + help='Port (%(default)s)', default=5000) + parser.add_argument('--char-limit', default=-1, type=int, metavar="", + help='Set character limit (%(default)s)') + parser.add_argument('--req-limit', default=-1, type=int, metavar="", + help='Set maximum number of requests per minute per client (%(default)s)') + parser.add_argument('--batch-limit', default=-1, type=int, metavar="", + help='Set maximum number of texts to translate in a batch request (%(default)s)') + parser.add_argument('--ga-id', type=str, default=None, metavar="", + help='Enable Google Analytics on the API client page by providing an ID (%(default)s)') + parser.add_argument('--debug', default=False, action="store_true", + help="Enable debug environment") + parser.add_argument('--ssl', default=None, action="store_true", + help="Whether to enable SSL") + parser.add_argument('--frontend-language-source', type=str, default="en", metavar="", + help='Set frontend default language - source (%(default)s)') + parser.add_argument('--frontend-language-target', type=str, default="es", metavar="", + help='Set frontend default language - target (%(default)s)') + parser.add_argument('--frontend-timeout', type=int, default=500, metavar="", + help='Set frontend translation timeout (%(default)s)') + + args = parser.parse_args() + + app = create_app(char_limit=args.char_limit, + req_limit=args.req_limit, + batch_limit=args.batch_limit, + ga_id=args.ga_id, + debug=args.debug, + frontend_language_source=args.frontend_language_source, + frontend_language_target=args.frontend_language_target, + frontend_timeout=args.frontend_timeout) + if args.debug: + app.run(host=args.host, port=args.port) + else: + from waitress import serve + serve(app, host=args.host, port=args.port, url_scheme='https' if args.ssl else 'http') + +if __name__ == "__main__": + main() diff --git a/main.py b/main.py deleted file mode 100644 index 348900d..0000000 --- a/main.py +++ /dev/null @@ -1,44 +0,0 @@ -import argparse -from app.app import create_app - -parser = argparse.ArgumentParser(description='LibreTranslate - Free and Open Source Translation API') -parser.add_argument('--host', type=str, - help='Hostname (%(default)s)', default="127.0.0.1") -parser.add_argument('--port', type=int, - help='Port (%(default)s)', default=5000) -parser.add_argument('--char-limit', default=-1, type=int, metavar="", - help='Set character limit (%(default)s)') -parser.add_argument('--req-limit', default=-1, type=int, metavar="", - help='Set maximum number of requests per minute per client (%(default)s)') -parser.add_argument('--batch-limit', default=-1, type=int, metavar="", - help='Set maximum number of texts to translate in a batch request (%(default)s)') -parser.add_argument('--ga-id', type=str, default=None, metavar="", - help='Enable Google Analytics on the API client page by providing an ID (%(default)s)') -parser.add_argument('--debug', default=False, action="store_true", - help="Enable debug environment") -parser.add_argument('--ssl', default=None, action="store_true", - help="Whether to enable SSL") -parser.add_argument('--frontend-language-source', type=str, default="en", metavar="", - help='Set frontend default language - source (%(default)s)') -parser.add_argument('--frontend-language-target', type=str, default="es", metavar="", - help='Set frontend default language - target (%(default)s)') -parser.add_argument('--frontend-timeout', type=int, default=500, metavar="", - help='Set frontend translation timeout (%(default)s)') - -args = parser.parse_args() - - -if __name__ == "__main__": - app = create_app(char_limit=args.char_limit, - req_limit=args.req_limit, - batch_limit=args.batch_limit, - ga_id=args.ga_id, - debug=args.debug, - frontend_language_source=args.frontend_language_source, - frontend_language_target=args.frontend_language_target, - frontend_timeout=args.frontend_timeout) - if args.debug: - app.run(host=args.host, port=args.port) - else: - from waitress import serve - serve(app, host=args.host, port=args.port, url_scheme='https' if args.ssl else 'http') diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..022ecef --- /dev/null +++ b/setup.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from setuptools import setup, find_packages + +setup( + version='1.1.0', + name='libretranslate', + license='GNU Affero General Public License v3.0', + description='Free and Open Source Machine Translation API. 100% self-hosted, no limits, no ties to proprietary services. Built on top of Argos Translate.', + author='Piero Toffanin', + author_email='pierotofy@email.com', + url='https://libretranslate.com', + packages=find_packages(), + # packages=find_packages(include=['openpredict']), + # package_dir={'openpredict': 'openpredict'}, + package_data={'': ['static/*', 'templates/*']}, + include_package_data=True, + entry_points={ + 'console_scripts': [ + 'libretranslate=app.main:main', + ], + }, + + python_requires='>=3.6.0', + long_description=open('README.md').read(), + long_description_content_type="text/markdown", + install_requires=open("requirements.txt", "r").readlines(), + tests_require=['pytest==5.2.0'], + setup_requires=['pytest-runner'], + classifiers=[ + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8" + ] +)