зеркало из https://github.com/mozilla/pontoon.git
Add support for Google AutoML Translation (#2648)
* Gracefully handle Google AutoML error when credentials not set * Prevent app crash on Heroku by forcing protobuf to use Python for parsing By default, protobuf uses C++ for parsing. The library includes prebuilt binary modules for Apple silicon, which my local box uses, so for me the library works as expected without this hack. I only noticed that's not the case for everyone after deploying to the stage server on Heroku. Read more: https://developers.google.com/protocol-buffers/docs/news/2022-05-06#python-updates https://developers.google.com/protocol-buffers/docs/reference/python-generated#sharing-messages * Add buildpack needed for authentication using Google Cloud service accounts And while we're at it, let's remove the unused buildpack.
This commit is contained in:
Родитель
4aa419cc6c
Коммит
ca67f5d312
7
app.json
7
app.json
|
@ -43,6 +43,11 @@
|
|||
"description": "Base URL of the site. Has to be https://{app-name}.herokuapp.com.",
|
||||
"required": true
|
||||
},
|
||||
"PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": {
|
||||
"value": "python",
|
||||
"description": "Needed for Google AutoML Translation.",
|
||||
"required": true
|
||||
},
|
||||
"ADMIN_EMAIL": {
|
||||
"value": "pontoon@example.com",
|
||||
"description": "Email address for the ``ADMINS`` setting."
|
||||
|
@ -124,7 +129,7 @@
|
|||
},
|
||||
"buildpacks": [
|
||||
{
|
||||
"url": "https://github.com/dmathieu/heroku-buildpack-submodules#0caf30af7737bf1bc32b7aafc009f19af3e603c1"
|
||||
"url": "https://github.com/gerywahyunugraha/heroku-google-application-credentials-buildpack.git"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/Osmose/heroku-buildpack-ssh"
|
||||
|
|
|
@ -9,3 +9,4 @@ FXA_CLIENT_ID=727f0251c388a993
|
|||
FXA_SECRET_KEY=e43fd751ca5687d28288098e3e9b1294792ed9954008388e39b1cdaac0a1ebd6
|
||||
FXA_OAUTH_ENDPOINT=https://oauth.stage.mozaws.net/v1
|
||||
FXA_PROFILE_ENDPOINT=https://profile.stage.mozaws.net/v1
|
||||
PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
|
||||
|
|
|
@ -136,8 +136,12 @@ you create:
|
|||
Optional. Set your `Google Analytics key`_ to use Google Analytics.
|
||||
|
||||
``GOOGLE_TRANSLATE_API_KEY``
|
||||
Optional. Set your `Google Cloud Translation API key`_ to use machine translation
|
||||
by Google.
|
||||
Optional. Set your `Google Cloud Translation API`_ key to use generic machine
|
||||
translation engine by Google.
|
||||
|
||||
``GOOGLE_AUTOML_PROJECT_ID``
|
||||
Optional. Set your `Google Cloud AutoML Translation`_ model ID to use custom machine
|
||||
translation engine by Google.
|
||||
|
||||
``LOCALE_REQUEST_FROM_EMAIL``
|
||||
Optional. Requests for new project locales are sent from this email.
|
||||
|
@ -154,7 +158,7 @@ you create:
|
|||
cloned into (it is located next to the "pontoon" Python module by default).
|
||||
|
||||
``MICROSOFT_TRANSLATOR_API_KEY``
|
||||
Optional. Set your `Microsoft Translator API key`_ to use machine translation
|
||||
Optional. Set your `Microsoft Translator API`_ key to use machine translation
|
||||
by Microsoft.
|
||||
|
||||
``NEW_RELIC_API_KEY``
|
||||
|
@ -168,6 +172,10 @@ you create:
|
|||
``PROJECT_MANAGERS``
|
||||
Optional. A list of project manager email addresses to send project requests to
|
||||
|
||||
``PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION``
|
||||
Required. Must be set to ``python``. Needed for Google AutoML Translation.
|
||||
Learn more on `Protocol Buffers Homepage`_.
|
||||
|
||||
``SECRET_KEY``
|
||||
Required. Secret key used for sessions, cryptographic signing, etc.
|
||||
|
||||
|
@ -249,9 +257,11 @@ you create:
|
|||
.. _the spec: https://github.com/mozilla/pontoon/blob/master/specs/0108-community-health-dashboard.md
|
||||
.. _Heroku Reference: https://devcenter.heroku.com/articles/error-pages#customize-pages
|
||||
.. _Firefox Accounts: https://developer.mozilla.org/docs/Mozilla/Tech/Firefox_Accounts/Introduction
|
||||
.. _Microsoft Translator API key: http://msdn.microsoft.com/en-us/library/hh454950
|
||||
.. _Microsoft Translator API: http://msdn.microsoft.com/en-us/library/hh454950
|
||||
.. _Google Analytics key: https://www.google.com/analytics/
|
||||
.. _Google Cloud Translation API key: https://cloud.google.com/translate/
|
||||
.. _Google Cloud Translation API: https://cloud.google.com/translate/
|
||||
.. _Google Cloud AutoML Translation: https://cloud.google.com/translate/
|
||||
.. _Protocol Buffers Homepage: https://developers.google.com/protocol-buffers/docs/news/2022-05-06#python-updates
|
||||
|
||||
Add-ons
|
||||
-------
|
||||
|
|
|
@ -175,14 +175,19 @@ Extra settings
|
|||
The following extra settings can be added to your ``.env`` file.
|
||||
|
||||
``GOOGLE_TRANSLATE_API_KEY``
|
||||
Set your `Google Cloud Translation API key`_ to use machine translation by Google.
|
||||
Set your `Google Cloud Translation API`_ key to use generic machine translation
|
||||
engine by Google.
|
||||
``GOOGLE_AUTOML_PROJECT_ID``
|
||||
Set your `Google Cloud AutoML Translation`_ model ID to use custom machine
|
||||
translation engine by Google.
|
||||
``MICROSOFT_TRANSLATOR_API_KEY``
|
||||
Set your `Microsoft Translator API key`_ to use machine translation by Microsoft.
|
||||
Set your `Microsoft Translator API`_ key to use machine translation by Microsoft.
|
||||
``GOOGLE_ANALYTICS_KEY``
|
||||
Set your `Google Analytics key`_ to use Google Analytics.
|
||||
``MANUAL_SYNC``
|
||||
Enable Sync button in project Admin.
|
||||
|
||||
.. _Microsoft Translator API key: http://msdn.microsoft.com/en-us/library/hh454950
|
||||
.. _Microsoft Translator API: http://msdn.microsoft.com/en-us/library/hh454950
|
||||
.. _Google Analytics key: https://www.google.com/analytics/
|
||||
.. _Google Cloud Translation API key: https://cloud.google.com/translate/
|
||||
.. _Google Cloud Translation API: https://cloud.google.com/translate/
|
||||
.. _Google Cloud AutoML Translation: https://cloud.google.com/translate/
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# Generated by Django 3.2.15 on 2022-11-02 22:22
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("base", "0035_ratio_to_rate"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="locale",
|
||||
name="google_automl_model",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
help_text="\n ID of a custom model, trained using locale translation memory. If the value is set,\n Pontoon will use the Google AutoML Translation instead of the generic Translation API.\n ",
|
||||
max_length=30,
|
||||
),
|
||||
),
|
||||
]
|
|
@ -696,6 +696,15 @@ class Locale(AggregatedStats):
|
|||
""",
|
||||
)
|
||||
|
||||
google_automl_model = models.CharField(
|
||||
max_length=30,
|
||||
blank=True,
|
||||
help_text="""
|
||||
ID of a custom model, trained using locale translation memory. If the value is set,
|
||||
Pontoon will use the Google AutoML Translation instead of the generic Translation API.
|
||||
""",
|
||||
)
|
||||
|
||||
# Codes used by optional Microsoft services
|
||||
ms_translator_code = models.CharField(
|
||||
max_length=20,
|
||||
|
|
|
@ -98,7 +98,7 @@ def test_view_google_translate(
|
|||
assert urllib.parse.parse_qs(req.query) == {
|
||||
"q": ["text"],
|
||||
"source": ["en"],
|
||||
"target": ["bg"],
|
||||
"target": ["google-translate"],
|
||||
"format": ["text"],
|
||||
"key": ["2fffff"],
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import json
|
||||
import Levenshtein
|
||||
import logging
|
||||
import operator
|
||||
import requests
|
||||
|
||||
from collections import defaultdict
|
||||
from functools import reduce
|
||||
from google.auth.exceptions import DefaultCredentialsError
|
||||
from google.cloud import translate
|
||||
|
||||
import Levenshtein
|
||||
import requests
|
||||
from django.conf import settings
|
||||
from django.contrib.postgres.aggregates import ArrayAgg
|
||||
from django.db.models import Q
|
||||
|
@ -17,6 +20,21 @@ MAX_RESULTS = 5
|
|||
|
||||
|
||||
def get_google_translate_data(text, locale_code):
|
||||
try:
|
||||
locale = base.models.Locale.objects.get(google_translate_code=locale_code)
|
||||
except base.models.Locale.DoesNotExist as e:
|
||||
return {
|
||||
"status": False,
|
||||
"message": f"{e}",
|
||||
}
|
||||
|
||||
if locale.google_automl_model:
|
||||
return get_google_automl_translation(text, locale)
|
||||
|
||||
return get_google_generic_translation(text, locale_code)
|
||||
|
||||
|
||||
def get_google_generic_translation(text, locale_code):
|
||||
api_key = settings.GOOGLE_TRANSLATE_API_KEY
|
||||
|
||||
if not api_key:
|
||||
|
@ -61,6 +79,56 @@ def get_google_translate_data(text, locale_code):
|
|||
}
|
||||
|
||||
|
||||
def get_google_automl_translation(text, locale):
|
||||
try:
|
||||
client = translate.TranslationServiceClient()
|
||||
except DefaultCredentialsError as e:
|
||||
log.error("Google AutoML Translation error: {e}")
|
||||
return {
|
||||
"status": False,
|
||||
"message": f"{e}",
|
||||
}
|
||||
|
||||
project_id = settings.GOOGLE_AUTOML_PROJECT_ID
|
||||
|
||||
if not project_id:
|
||||
log.error("GOOGLE_AUTOML_PROJECT_ID not set")
|
||||
return {
|
||||
"status": False,
|
||||
"message": "Bad Request: Missing Project ID.",
|
||||
}
|
||||
|
||||
model_id = locale.google_automl_model
|
||||
|
||||
# Google AutoML Translation requires location "us-central1"
|
||||
location = "us-central1"
|
||||
|
||||
parent = f"projects/{project_id}/locations/{location}"
|
||||
model_path = f"{parent}/models/{model_id}"
|
||||
|
||||
response = client.translate_text(
|
||||
request={
|
||||
"contents": [text],
|
||||
"target_language_code": locale.google_translate_code,
|
||||
"model": model_path,
|
||||
"source_language_code": "en",
|
||||
"parent": parent,
|
||||
"mime_type": "text/plain",
|
||||
}
|
||||
)
|
||||
|
||||
if len(response.translations) == 0:
|
||||
return {
|
||||
"status": False,
|
||||
"message": "No translations found.",
|
||||
}
|
||||
else:
|
||||
return {
|
||||
"status": True,
|
||||
"translation": response.translations[0].translated_text,
|
||||
}
|
||||
|
||||
|
||||
def get_concordance_search_data(text, locale):
|
||||
search_phrases = base.utils.get_search_phrases(text)
|
||||
search_filters = (
|
||||
|
|
|
@ -102,6 +102,9 @@ BROKER_URL = os.environ.get("RABBITMQ_URL", None)
|
|||
# Google Cloud Translation API key
|
||||
GOOGLE_TRANSLATE_API_KEY = os.environ.get("GOOGLE_TRANSLATE_API_KEY", "")
|
||||
|
||||
# Google Cloud AutoML Translation Project ID
|
||||
GOOGLE_AUTOML_PROJECT_ID = os.environ.get("GOOGLE_AUTOML_PROJECT_ID", "")
|
||||
|
||||
# Microsoft Translator API Key
|
||||
MICROSOFT_TRANSLATOR_API_KEY = os.environ.get("MICROSOFT_TRANSLATOR_API_KEY", "")
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ def locale_a():
|
|||
@pytest.fixture
|
||||
def google_translate_locale(locale_a):
|
||||
"""Set the Google Cloud Translation API locale code for locale_a"""
|
||||
locale_a.google_translate_code = "bg"
|
||||
locale_a.google_translate_code = "google-translate"
|
||||
locale_a.save()
|
||||
return locale_a
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ django-guardian==2.3.0
|
|||
django-jinja==2.7.0
|
||||
django-notifications-hq==1.6.0
|
||||
django-pipeline==2.0.6
|
||||
google-cloud-translate==3.8.4
|
||||
graphene-django==2.13.0
|
||||
gunicorn==19.9.0
|
||||
jsonfield==3.1.0
|
||||
|
|
|
@ -27,6 +27,10 @@ bleach==3.3.0 \
|
|||
blinker==1.4 \
|
||||
--hash=sha256:471aee25f3992bd325afa3772f1063dbdbbca947a041b8b89466dc00d606f8b6
|
||||
# via raygun4py
|
||||
cachetools==5.2.0 \
|
||||
--hash=sha256:6a94c6402995a99c3970cc7e4884bb60b4a8639938157eeed436098bf9831757 \
|
||||
--hash=sha256:f9f17d2aec496a9aa6b76f53e3b614c965223c061982d434d160f930c698a9db
|
||||
# via google-auth
|
||||
celery==5.2.6 \
|
||||
--hash=sha256:d1398cadf30f576266b34370e28e880306ec55f7a4b6307549b0ae9c15663481 \
|
||||
--hash=sha256:da31f8eae7607b1582e5ee2d3f2d6f58450585afd23379491e3d9229d08102d0
|
||||
|
@ -208,6 +212,32 @@ fluent-syntax==0.18.1 \
|
|||
--hash=sha256:0e63679fa4f1b3042565220a5127b4bab842424f07d6a13c12299e3b3835486a \
|
||||
--hash=sha256:3a55f5e605d1b029a65cc8b6492c86ec4608e15447e73db1495de11fd46c104f
|
||||
# via compare-locales
|
||||
google-api-core[grpc]==2.10.2 \
|
||||
--hash=sha256:10c06f7739fe57781f87523375e8e1a3a4674bf6392cd6131a3222182b971320 \
|
||||
--hash=sha256:34f24bd1d5f72a8c4519773d99ca6bf080a6c4e041b4e9f024fe230191dda62e
|
||||
# via
|
||||
# google-cloud-core
|
||||
# google-cloud-translate
|
||||
google-auth==2.13.0 \
|
||||
--hash=sha256:9352dd6394093169157e6971526bab9a2799244d68a94a4a609f0dd751ef6f5e \
|
||||
--hash=sha256:99510e664155f1a3c0396a076b5deb6367c52ea04d280152c85ac7f51f50eb42
|
||||
# via
|
||||
# google-api-core
|
||||
# google-cloud-core
|
||||
google-cloud-core==2.3.2 \
|
||||
--hash=sha256:8417acf6466be2fa85123441696c4badda48db314c607cf1e5d543fa8bdc22fe \
|
||||
--hash=sha256:b9529ee7047fd8d4bf4a2182de619154240df17fbe60ead399078c1ae152af9a
|
||||
# via google-cloud-translate
|
||||
google-cloud-translate==3.8.4 \
|
||||
--hash=sha256:729b52172001c99459ec3afddec9153de0af528874fcf3000a9ddd98e1107ee7 \
|
||||
--hash=sha256:e1099ef7b288d7e8e4ea9c47be50129459890fdaa590c754ef848de74b7cd9ec
|
||||
# via -r requirements/default.in
|
||||
googleapis-common-protos==1.56.4 \
|
||||
--hash=sha256:8eb2cbc91b69feaf23e32452a7ae60e791e09967d81d4fcc7fc388182d1bd394 \
|
||||
--hash=sha256:c25873c47279387cfdcbdafa36149887901d36202cb645a0e4f29686bf6e4417
|
||||
# via
|
||||
# google-api-core
|
||||
# grpcio-status
|
||||
graphene==2.1.9 \
|
||||
--hash=sha256:3d446eb1237c551052bc31155cf1a3a607053e4f58c9172b83a1b597beaa0868 \
|
||||
--hash=sha256:b9f2850e064eebfee9a3ef4a1f8aa0742848d97652173ab44c82cc8a62b9ed93
|
||||
|
@ -227,6 +257,59 @@ graphql-relay==2.0.1 \
|
|||
--hash=sha256:870b6b5304123a38a0b215a79eace021acce5a466bf40cd39fa18cb8528afabb \
|
||||
--hash=sha256:ac514cb86db9a43014d7e73511d521137ac12cf0101b2eaa5f0a3da2e10d913d
|
||||
# via graphene
|
||||
grpcio==1.50.0 \
|
||||
--hash=sha256:05f7c248e440f538aaad13eee78ef35f0541e73498dd6f832fe284542ac4b298 \
|
||||
--hash=sha256:080b66253f29e1646ac53ef288c12944b131a2829488ac3bac8f52abb4413c0d \
|
||||
--hash=sha256:12b479839a5e753580b5e6053571de14006157f2ef9b71f38c56dc9b23b95ad6 \
|
||||
--hash=sha256:156f8009e36780fab48c979c5605eda646065d4695deea4cfcbcfdd06627ddb6 \
|
||||
--hash=sha256:15f9e6d7f564e8f0776770e6ef32dac172c6f9960c478616c366862933fa08b4 \
|
||||
--hash=sha256:177afaa7dba3ab5bfc211a71b90da1b887d441df33732e94e26860b3321434d9 \
|
||||
--hash=sha256:1a4cd8cb09d1bc70b3ea37802be484c5ae5a576108bad14728f2516279165dd7 \
|
||||
--hash=sha256:1d8d02dbb616c0a9260ce587eb751c9c7dc689bc39efa6a88cc4fa3e9c138a7b \
|
||||
--hash=sha256:2b71916fa8f9eb2abd93151fafe12e18cebb302686b924bd4ec39266211da525 \
|
||||
--hash=sha256:2d9fd6e38b16c4d286a01e1776fdf6c7a4123d99ae8d6b3f0b4a03a34bf6ce45 \
|
||||
--hash=sha256:3b611b3de3dfd2c47549ca01abfa9bbb95937eb0ea546ea1d762a335739887be \
|
||||
--hash=sha256:3e4244c09cc1b65c286d709658c061f12c61c814be0b7030a2d9966ff02611e0 \
|
||||
--hash=sha256:40838061e24f960b853d7bce85086c8e1b81c6342b1f4c47ff0edd44bbae2722 \
|
||||
--hash=sha256:4b123fbb7a777a2fedec684ca0b723d85e1d2379b6032a9a9b7851829ed3ca9a \
|
||||
--hash=sha256:531f8b46f3d3db91d9ef285191825d108090856b3bc86a75b7c3930f16ce432f \
|
||||
--hash=sha256:67dd41a31f6fc5c7db097a5c14a3fa588af54736ffc174af4411d34c4f306f68 \
|
||||
--hash=sha256:7489dbb901f4fdf7aec8d3753eadd40839c9085967737606d2c35b43074eea24 \
|
||||
--hash=sha256:8d4c8e73bf20fb53fe5a7318e768b9734cf122fe671fcce75654b98ba12dfb75 \
|
||||
--hash=sha256:8e69aa4e9b7f065f01d3fdcecbe0397895a772d99954bb82eefbb1682d274518 \
|
||||
--hash=sha256:8e8999a097ad89b30d584c034929f7c0be280cd7851ac23e9067111167dcbf55 \
|
||||
--hash=sha256:906f4d1beb83b3496be91684c47a5d870ee628715227d5d7c54b04a8de802974 \
|
||||
--hash=sha256:92d7635d1059d40d2ec29c8bf5ec58900120b3ce5150ef7414119430a4b2dd5c \
|
||||
--hash=sha256:931e746d0f75b2a5cff0a1197d21827a3a2f400c06bace036762110f19d3d507 \
|
||||
--hash=sha256:95ce51f7a09491fb3da8cf3935005bff19983b77c4e9437ef77235d787b06842 \
|
||||
--hash=sha256:9eea18a878cffc804506d39c6682d71f6b42ec1c151d21865a95fae743fda500 \
|
||||
--hash=sha256:a23d47f2fc7111869f0ff547f771733661ff2818562b04b9ed674fa208e261f4 \
|
||||
--hash=sha256:a4c23e54f58e016761b576976da6a34d876420b993f45f66a2bfb00363ecc1f9 \
|
||||
--hash=sha256:a50a1be449b9e238b9bd43d3857d40edf65df9416dea988929891d92a9f8a778 \
|
||||
--hash=sha256:ab5d0e3590f0a16cb88de4a3fa78d10eb66a84ca80901eb2c17c1d2c308c230f \
|
||||
--hash=sha256:ae23daa7eda93c1c49a9ecc316e027ceb99adbad750fbd3a56fa9e4a2ffd5ae0 \
|
||||
--hash=sha256:af98d49e56605a2912cf330b4627e5286243242706c3a9fa0bcec6e6f68646fc \
|
||||
--hash=sha256:b2f77a90ba7b85bfb31329f8eab9d9540da2cf8a302128fb1241d7ea239a5469 \
|
||||
--hash=sha256:baab51dcc4f2aecabf4ed1e2f57bceab240987c8b03533f1cef90890e6502067 \
|
||||
--hash=sha256:ca8a2254ab88482936ce941485c1c20cdeaef0efa71a61dbad171ab6758ec998 \
|
||||
--hash=sha256:cb11464f480e6103c59d558a3875bd84eed6723f0921290325ebe97262ae1347 \
|
||||
--hash=sha256:ce8513aee0af9c159319692bfbf488b718d1793d764798c3d5cff827a09e25ef \
|
||||
--hash=sha256:cf151f97f5f381163912e8952eb5b3afe89dec9ed723d1561d59cabf1e219a35 \
|
||||
--hash=sha256:d144ad10eeca4c1d1ce930faa105899f86f5d99cecfe0d7224f3c4c76265c15e \
|
||||
--hash=sha256:d534d169673dd5e6e12fb57cc67664c2641361e1a0885545495e65a7b761b0f4 \
|
||||
--hash=sha256:d75061367a69808ab2e84c960e9dce54749bcc1e44ad3f85deee3a6c75b4ede9 \
|
||||
--hash=sha256:d84d04dec64cc4ed726d07c5d17b73c343c8ddcd6b59c7199c801d6bbb9d9ed1 \
|
||||
--hash=sha256:de411d2b030134b642c092e986d21aefb9d26a28bf5a18c47dd08ded411a3bc5 \
|
||||
--hash=sha256:e07fe0d7ae395897981d16be61f0db9791f482f03fee7d1851fe20ddb4f69c03 \
|
||||
--hash=sha256:ea8ccf95e4c7e20419b7827aa5b6da6f02720270686ac63bd3493a651830235c \
|
||||
--hash=sha256:f7025930039a011ed7d7e7ef95a1cb5f516e23c5a6ecc7947259b67bea8e06ca
|
||||
# via
|
||||
# google-api-core
|
||||
# grpcio-status
|
||||
grpcio-status==1.50.0 \
|
||||
--hash=sha256:69be81c4317ec77983fb0eab80221a01e86e833e0fcf2f6acea0a62597c84b93 \
|
||||
--hash=sha256:6bcf86b1cb1a8929c9cb75c8593ea001a667f5167cf692627f4b3fc1ae0eded4
|
||||
# via google-api-core
|
||||
gunicorn==19.9.0 \
|
||||
--hash=sha256:aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471 \
|
||||
--hash=sha256:fa2662097c66f920f53f70621c6c58ca4a3c4d3434205e608e121b5b3b71f4f3
|
||||
|
@ -451,6 +534,31 @@ prompt-toolkit==3.0.29 \
|
|||
--hash=sha256:62291dad495e665fca0bda814e342c69952086afb0f4094d0893d357e5c78752 \
|
||||
--hash=sha256:bd640f60e8cecd74f0dc249713d433ace2ddc62b65ee07f96d358e0b152b6ea7
|
||||
# via click-repl
|
||||
proto-plus==1.22.1 \
|
||||
--hash=sha256:6c7dfd122dfef8019ff654746be4f5b1d9c80bba787fe9611b508dd88be3a2fa \
|
||||
--hash=sha256:ea8982669a23c379f74495bc48e3dcb47c822c484ce8ee1d1d7beb339d4e34c5
|
||||
# via google-cloud-translate
|
||||
protobuf==4.21.8 \
|
||||
--hash=sha256:0f236ce5016becd989bf39bd20761593e6d8298eccd2d878eda33012645dc369 \
|
||||
--hash=sha256:2c92a7bfcf4ae76a8ac72e545e99a7407e96ffe52934d690eb29a8809ee44d7b \
|
||||
--hash=sha256:427426593b55ff106c84e4a88cac855175330cb6eb7e889e85aaa7b5652b686d \
|
||||
--hash=sha256:4761201b93e024bb70ee3a6a6425d61f3152ca851f403ba946fb0cde88872661 \
|
||||
--hash=sha256:809ca0b225d3df42655a12f311dd0f4148a943c51f1ad63c38343e457492b689 \
|
||||
--hash=sha256:89d641be4b5061823fa0e463c50a2607a97833e9f8cfb36c2f91ef5ccfcc3861 \
|
||||
--hash=sha256:a55545ce9eec4030cf100fcb93e861c622d927ef94070c1a3c01922902464278 \
|
||||
--hash=sha256:b02eabb9ebb1a089ed20626a90ad7a69cee6bcd62c227692466054b19c38dd1f \
|
||||
--hash=sha256:b37b76efe84d539f16cba55ee0036a11ad91300333abd213849cbbbb284b878e \
|
||||
--hash=sha256:bbececaf3cfea9ea65ebb7974e6242d310d2a7772a6f015477e0d79993af4511 \
|
||||
--hash=sha256:bc471cf70a0f53892fdd62f8cd4215f0af8b3f132eeee002c34302dff9edd9b6 \
|
||||
--hash=sha256:c252c55ee15175aa1b21b7b9896e6add5162d066d5202e75c39f96136f08cce3 \
|
||||
--hash=sha256:c5f94911dd8feb3cd3786fc90f7565c9aba7ce45d0f254afd625b9628f578c3f \
|
||||
--hash=sha256:f2d55ff22ec300c4d954d3b0d1eeb185681ec8ad4fbecff8a5aee6a1cdd345ba
|
||||
# via
|
||||
# google-api-core
|
||||
# google-cloud-translate
|
||||
# googleapis-common-protos
|
||||
# grpcio-status
|
||||
# proto-plus
|
||||
psycopg2==2.8.5 \
|
||||
--hash=sha256:132efc7ee46a763e68a815f4d26223d9c679953cd190f1f218187cb60decf535 \
|
||||
--hash=sha256:2327bf42c1744a434ed8ed0bbaa9168cac7ee5a22a9001f6fc85c33b8a4a14b7 \
|
||||
|
@ -466,6 +574,16 @@ psycopg2==2.8.5 \
|
|||
--hash=sha256:d3b29d717d39d3580efd760a9a46a7418408acebbb784717c90d708c9ed5f055 \
|
||||
--hash=sha256:f7d46240f7a1ae1dd95aab38bd74f7428d46531f69219954266d669da60c0818
|
||||
# via -r requirements/default.in
|
||||
pyasn1==0.4.8 \
|
||||
--hash=sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d \
|
||||
--hash=sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba
|
||||
# via
|
||||
# pyasn1-modules
|
||||
# rsa
|
||||
pyasn1-modules==0.2.8 \
|
||||
--hash=sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e \
|
||||
--hash=sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74
|
||||
# via google-auth
|
||||
pycparser==2.21 \
|
||||
--hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \
|
||||
--hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206
|
||||
|
@ -571,12 +689,17 @@ requests==2.26.0 \
|
|||
--hash=sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7
|
||||
# via
|
||||
# django-allauth
|
||||
# google-api-core
|
||||
# raygun4py
|
||||
# requests-oauthlib
|
||||
requests-oauthlib==1.3.0 \
|
||||
--hash=sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d \
|
||||
--hash=sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a
|
||||
# via django-allauth
|
||||
rsa==4.9 \
|
||||
--hash=sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7 \
|
||||
--hash=sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21
|
||||
# via google-auth
|
||||
rx==1.6.1 \
|
||||
--hash=sha256:13a1d8d9e252625c173dc795471e614eadfe1cf40ffc684e08b8fff0d9748c23 \
|
||||
--hash=sha256:7357592bc7e881a95e0c2013b73326f704953301ab551fbc8133a6fadab84105
|
||||
|
@ -598,10 +721,12 @@ six==1.16.0 \
|
|||
# bleach
|
||||
# click-repl
|
||||
# compare-locales
|
||||
# google-auth
|
||||
# graphene
|
||||
# graphene-django
|
||||
# graphql-core
|
||||
# graphql-relay
|
||||
# grpcio
|
||||
# parsimonious
|
||||
# promise
|
||||
# python-binary-memcached
|
||||
|
|
Загрузка…
Ссылка в новой задаче