Skip to content

Commit

Permalink
chore: delay some third-party imports
Browse files Browse the repository at this point in the history
These are not used frequently and delaying makes positive impact on
startup performance and memory usage.
  • Loading branch information
nijel committed May 22, 2024
1 parent d8c046b commit 101d287
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 16 deletions.
6 changes: 3 additions & 3 deletions weblate/checks/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@

from operator import itemgetter

from pygments.lexers.markup import RstLexer
from pygments.token import Token

from weblate.checks.models import CHECKS


Expand All @@ -17,6 +14,9 @@ def highlight_pygments(source: str, unit):
This is not really a full syntax highlighting, we're only interested in
non-translatable strings.
"""
from pygments.lexers.markup import RstLexer
from pygments.token import Token

if "rst-text" in unit.all_flags:
lexer = RstLexer(stripnl=False)
start = 0
Expand Down
3 changes: 2 additions & 1 deletion weblate/fonts/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import gi
from django.conf import settings
from django.core.cache import cache as django_cache
from PIL import ImageFont

from weblate.utils.data import data_dir

Expand Down Expand Up @@ -259,6 +258,8 @@ def check_render_size(

def get_font_name(filelike):
"""Return tuple of font family and style, for example ('Ubuntu', 'Regular')."""
from PIL import ImageFont

if not hasattr(filelike, "loaded_font"):
# The tempfile creation is workaround for Pillow crashing on invalid font
# see https://github.com/python-pillow/Pillow/issues/3853
Expand Down
11 changes: 8 additions & 3 deletions weblate/formats/external.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
from zipfile import BadZipFile

from django.utils.translation import gettext_lazy
from openpyxl import Workbook, load_workbook
from openpyxl.cell.cell import TYPE_STRING
from openpyxl.workbook.child import INVALID_TITLE_REGEX
from translate.storage.csvl10n import csv

from weblate.formats.helpers import CONTROLCHARS_TRANS, NamedBytesIO
Expand All @@ -30,13 +27,17 @@ class XlsxFormat(CSVFormat):
autoload = ("*.xlsx",)

def write_cell(self, worksheet, column: int, row: int, value: str):
from openpyxl.cell.cell import TYPE_STRING

cell = worksheet.cell(column=column, row=row)
cell.value = value
# Set the data_type after value to override function auto-detection
cell.data_type = TYPE_STRING
return cell

def get_title(self, fallback: str = "Weblate"):
from openpyxl.workbook.child import INVALID_TITLE_REGEX

title = self.store.targetlanguage
if title is None:
return fallback
Expand All @@ -47,6 +48,8 @@ def get_title(self, fallback: str = "Weblate"):
return title

def save_content(self, handle) -> None:
from openpyxl import Workbook

workbook = Workbook()
worksheet = workbook.active
worksheet.title = self.get_title()
Expand Down Expand Up @@ -77,6 +80,8 @@ def serialize(store):
return output.getvalue()

def parse_store(self, storefile):
from openpyxl import load_workbook

# try to load the given file via openpyxl
# catch at least the BadZipFile exception if an unsupported
# file has been given
Expand Down
3 changes: 2 additions & 1 deletion weblate/machinery/aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later

import boto3
from django.utils.functional import cached_property

from .base import DownloadTranslations, MachineTranslation
Expand All @@ -26,6 +25,8 @@ def get_identifier(cls) -> str:

@cached_property
def client(self):
import boto3

return boto3.client(
service_name="translate",
region_name=self.settings["region"],
Expand Down
12 changes: 7 additions & 5 deletions weblate/machinery/openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@
from typing import TYPE_CHECKING, Literal

from django.core.cache import cache
from openai import OpenAI
from openai.types.chat import (
ChatCompletionSystemMessageParam,
ChatCompletionUserMessageParam,
)

from weblate.glossary.models import (
get_glossary_terms,
Expand Down Expand Up @@ -66,6 +61,8 @@ class OpenAITranslation(BatchMachineTranslation):
settings_form = OpenAIMachineryForm

def __init__(self, settings=None) -> None:
from openai import OpenAI

super().__init__(settings)
self.client = OpenAI(api_key=self.settings["key"], timeout=self.request_timeout)
self._models: None | set[str] = None
Expand Down Expand Up @@ -135,6 +132,11 @@ def download_multiple_translations(
user=None,
threshold: int = 75,
) -> DownloadMultipleTranslations:
from openai.types.chat import (
ChatCompletionSystemMessageParam,
ChatCompletionUserMessageParam,
)

texts = [text for text, _unit in sources]
units = [unit for _text, unit in sources]
prompt = self.get_prompt(source, language, texts, units)
Expand Down
10 changes: 8 additions & 2 deletions weblate/screenshots/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
from django.utils.translation import gettext
from django.views.decorators.http import require_POST
from django.views.generic import DetailView, ListView
from PIL import Image
from tesserocr import OEM, PSM, RIL, PyTessBaseAPI, iterate_level

from weblate.logger import LOGGER
from weblate.screenshots.forms import ScreenshotEditForm, ScreenshotForm, SearchForm
Expand All @@ -33,6 +31,8 @@
from weblate.utils.views import PathViewMixin

if TYPE_CHECKING:
from tesserocr import PyTessBaseAPI

from weblate.auth.models import AuthenticatedHttpRequest
from weblate.lang.models import Language

Expand Down Expand Up @@ -371,6 +371,8 @@ def search_source(request, pk):


def ocr_get_strings(api, image: str, resolution: int = 72):
from tesserocr import RIL, iterate_level

try:
api.SetImageFile(image)
except RuntimeError:
Expand Down Expand Up @@ -404,6 +406,8 @@ def ocr_extract(api, image: str, strings, resolution: int):

@contextmanager
def get_tesseract(language: Language) -> PyTessBaseAPI:
from tesserocr import OEM, PSM, PyTessBaseAPI

# Get matching language
try:
tess_language = TESSERACT_LANGUAGES[language.code]
Expand All @@ -427,6 +431,8 @@ def get_tesseract(language: Language) -> PyTessBaseAPI:
@login_required
@require_POST
def ocr_search(request, pk):
from PIL import Image

obj = get_screenshot(request, pk)
translation = obj.translation

Expand Down
3 changes: 2 additions & 1 deletion weblate/utils/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
from django.core.validators import EmailValidator as EmailValidatorDjango
from django.core.validators import URLValidator, validate_ipv46_address
from django.utils.translation import gettext, gettext_lazy
from PIL import Image

from weblate.trans.util import cleanup_path
from weblate.utils.data import data_dir
Expand Down Expand Up @@ -80,6 +79,8 @@ def validate_re_nonempty(value):

def validate_bitmap(value) -> None:
"""Validate bitmap, based on django.forms.fields.ImageField."""
from PIL import Image

if value is None:
return

Expand Down

0 comments on commit 101d287

Please sign in to comment.