feat: manage Python 3 compatiblity with dependencies
This commit is contained in:
parent
83ee74c074
commit
3142723d41
12 changed files with 238 additions and 205 deletions
6
.github/workflows/ci-tests.yml
vendored
6
.github/workflows/ci-tests.yml
vendored
|
|
@ -149,9 +149,9 @@ jobs:
|
|||
run: |
|
||||
cp ~/frappe-bench/sites/.coverage ${GITHUB_WORKSPACE}
|
||||
cd ${GITHUB_WORKSPACE}
|
||||
pip install coveralls==2.2.0
|
||||
pip install coverage==4.5.4
|
||||
coveralls
|
||||
pip install coveralls==3.0.1
|
||||
pip install coverage==5.5
|
||||
coveralls --service=github
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }}
|
||||
|
|
|
|||
|
|
@ -676,10 +676,8 @@ def start_ngrok(context):
|
|||
frappe.init(site=site)
|
||||
|
||||
port = frappe.conf.http_port or frappe.conf.webserver_port
|
||||
public_url = ngrok.connect(port=port, options={
|
||||
'host_header': site
|
||||
})
|
||||
print(f'Public URL: {public_url}')
|
||||
tunnel = ngrok.connect(addr=str(port), host_header=site)
|
||||
print(f'Public URL: {tunnel.public_url}')
|
||||
print('Inspect logs at http://localhost:4040')
|
||||
|
||||
ngrok_process = ngrok.get_ngrok_process()
|
||||
|
|
|
|||
|
|
@ -2,14 +2,15 @@
|
|||
# Copyright (c) 2019, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import json
|
||||
from datetime import datetime
|
||||
from typing import Dict, List
|
||||
|
||||
import frappe, json
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import now_datetime, get_datetime
|
||||
from datetime import datetime
|
||||
from croniter import croniter
|
||||
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import get_datetime, now_datetime
|
||||
from frappe.utils.background_jobs import enqueue, get_jobs
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,13 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import warnings
|
||||
|
||||
import pymysql
|
||||
from pymysql.times import TimeDelta
|
||||
from pymysql.constants import ER, FIELD_TYPE
|
||||
from pymysql.converters import conversions
|
||||
from pymysql.constants import ER, FIELD_TYPE
|
||||
from pymysql.converters import conversions, escape_string
|
||||
|
||||
from frappe.utils import get_datetime, cstr, UnicodeWithAttrs
|
||||
import frappe
|
||||
from frappe.database.database import Database
|
||||
from six import PY2, binary_type, text_type, string_types
|
||||
from frappe.database.mariadb.schema import MariaDBTable
|
||||
from frappe.utils import UnicodeWithAttrs, cstr, get_datetime
|
||||
|
||||
|
||||
class MariaDBDatabase(Database):
|
||||
|
|
@ -72,22 +68,20 @@ class MariaDBDatabase(Database):
|
|||
conversions.update({
|
||||
FIELD_TYPE.NEWDECIMAL: float,
|
||||
FIELD_TYPE.DATETIME: get_datetime,
|
||||
UnicodeWithAttrs: conversions[text_type]
|
||||
UnicodeWithAttrs: conversions[str]
|
||||
})
|
||||
|
||||
if PY2:
|
||||
conversions.update({
|
||||
TimeDelta: conversions[binary_type]
|
||||
})
|
||||
|
||||
if usessl:
|
||||
conn = pymysql.connect(self.host, self.user or '', self.password or '',
|
||||
port=self.port, charset='utf8mb4', use_unicode = True, ssl=ssl_params,
|
||||
conv = conversions, local_infile = frappe.conf.local_infile)
|
||||
else:
|
||||
conn = pymysql.connect(self.host, self.user or '', self.password or '',
|
||||
port=self.port, charset='utf8mb4', use_unicode = True, conv = conversions,
|
||||
local_infile = frappe.conf.local_infile)
|
||||
conn = pymysql.connect(
|
||||
user=self.user or '',
|
||||
password=self.password or '',
|
||||
host=self.host,
|
||||
port=self.port,
|
||||
charset='utf8mb4',
|
||||
use_unicode=True,
|
||||
ssl=ssl_params if usessl else None,
|
||||
conv=conversions,
|
||||
local_infile=frappe.conf.local_infile
|
||||
)
|
||||
|
||||
# MYSQL_OPTION_MULTI_STATEMENTS_OFF = 1
|
||||
# # self._conn.set_server_option(MYSQL_OPTION_MULTI_STATEMENTS_OFF)
|
||||
|
|
@ -111,7 +105,7 @@ class MariaDBDatabase(Database):
|
|||
def escape(s, percent=True):
|
||||
"""Excape quotes and percent in given string."""
|
||||
# pymysql expects unicode argument to escape_string with Python 3
|
||||
s = frappe.as_unicode(pymysql.escape_string(frappe.as_unicode(s)), "utf-8").replace("`", "\\`")
|
||||
s = frappe.as_unicode(escape_string(frappe.as_unicode(s)), "utf-8").replace("`", "\\`")
|
||||
|
||||
# NOTE separating % escape, because % escape should only be done when using LIKE operator
|
||||
# or when you use python format string to generate query that already has a %s
|
||||
|
|
@ -260,7 +254,7 @@ class MariaDBDatabase(Database):
|
|||
ADD INDEX `%s`(%s)""" % (table_name, index_name, ", ".join(fields)))
|
||||
|
||||
def add_unique(self, doctype, fields, constraint_name=None):
|
||||
if isinstance(fields, string_types):
|
||||
if isinstance(fields, str):
|
||||
fields = [fields]
|
||||
if not constraint_name:
|
||||
constraint_name = "unique_" + "_".join(fields)
|
||||
|
|
|
|||
|
|
@ -1,18 +1,27 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# MIT License. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import six
|
||||
from six import iteritems, text_type
|
||||
from six.moves import range
|
||||
import time, _socket, poplib, imaplib, email, email.utils, datetime, chardet, re
|
||||
from email_reply_parser import EmailReplyParser
|
||||
import datetime
|
||||
import email
|
||||
import email.utils
|
||||
import imaplib
|
||||
import poplib
|
||||
import re
|
||||
import time
|
||||
from email.header import decode_header
|
||||
|
||||
import _socket
|
||||
import chardet
|
||||
import six
|
||||
from email_reply_parser import EmailReplyParser
|
||||
|
||||
import frappe
|
||||
from frappe import _, safe_decode, safe_encode
|
||||
from frappe.utils import (extract_email_id, convert_utc_to_user_timezone, now,
|
||||
cint, cstr, strip, markdown, parse_addr)
|
||||
from frappe.core.doctype.file.file import get_random_filename, MaxFileSizeReachedError
|
||||
from frappe.core.doctype.file.file import (MaxFileSizeReachedError,
|
||||
get_random_filename)
|
||||
from frappe.utils import (cint, convert_utc_to_user_timezone, cstr,
|
||||
extract_email_id, markdown, now, parse_addr, strip)
|
||||
|
||||
|
||||
class EmailSizeExceededError(frappe.ValidationError): pass
|
||||
class EmailTimeoutError(frappe.ValidationError): pass
|
||||
|
|
@ -337,7 +346,7 @@ class EmailServer:
|
|||
return
|
||||
|
||||
self.imap.select("Inbox")
|
||||
for uid, operation in iteritems(uid_list):
|
||||
for uid, operation in uid_list.items():
|
||||
if not uid: continue
|
||||
|
||||
op = "+FLAGS" if operation == "Read" else "-FLAGS"
|
||||
|
|
@ -473,7 +482,7 @@ class Email:
|
|||
self.html_content += markdown(text_content)
|
||||
|
||||
def get_charset(self, part):
|
||||
"""Detect chartset."""
|
||||
"""Detect charset."""
|
||||
charset = part.get_content_charset()
|
||||
if not charset:
|
||||
charset = chardet.detect(safe_encode(cstr(part)))['encoding']
|
||||
|
|
@ -484,7 +493,7 @@ class Email:
|
|||
charset = self.get_charset(part)
|
||||
|
||||
try:
|
||||
return text_type(part.get_payload(decode=True), str(charset), "ignore")
|
||||
return str(part.get_payload(decode=True), str(charset), "ignore")
|
||||
except LookupError:
|
||||
return part.get_payload()
|
||||
|
||||
|
|
|
|||
|
|
@ -2,22 +2,23 @@
|
|||
# Copyright (c) 2015, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import dropbox
|
||||
import json
|
||||
import frappe
|
||||
import os
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.integrations.offsite_backup_utils import get_latest_backup_file, send_email, validate_file_size, get_chunk_site
|
||||
from frappe.integrations.utils import make_post_request
|
||||
from frappe.utils import (cint, get_request_site_address,
|
||||
get_files_path, get_backups_path, get_url, encode)
|
||||
from frappe.utils.backups import new_backup
|
||||
from frappe.utils.background_jobs import enqueue
|
||||
from six.moves.urllib.parse import urlparse, parse_qs
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
|
||||
import dropbox
|
||||
from rq.timeouts import JobTimeoutException
|
||||
from six import text_type
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.integrations.offsite_backup_utils import (get_chunk_site,
|
||||
get_latest_backup_file, send_email, validate_file_size)
|
||||
from frappe.integrations.utils import make_post_request
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import (cint, encode, get_backups_path, get_files_path,
|
||||
get_request_site_address, get_url)
|
||||
from frappe.utils.background_jobs import enqueue
|
||||
from frappe.utils.backups import new_backup
|
||||
|
||||
ignore_list = [".DS_Store"]
|
||||
|
||||
|
|
@ -91,7 +92,10 @@ def backup_to_dropbox(upload_db_backup=True):
|
|||
dropbox_settings['access_token'] = access_token['oauth2_token']
|
||||
set_dropbox_access_token(access_token['oauth2_token'])
|
||||
|
||||
dropbox_client = dropbox.Dropbox(dropbox_settings['access_token'], timeout=None)
|
||||
dropbox_client = dropbox.Dropbox(
|
||||
oauth2_access_token=dropbox_settings['access_token'],
|
||||
timeout=None
|
||||
)
|
||||
|
||||
if upload_db_backup:
|
||||
if frappe.flags.create_new_backup:
|
||||
|
|
@ -127,7 +131,7 @@ def upload_from_folder(path, is_private, dropbox_folder, dropbox_client, did_not
|
|||
else:
|
||||
response = frappe._dict({"entries": []})
|
||||
|
||||
path = text_type(path)
|
||||
path = str(path)
|
||||
|
||||
for f in frappe.get_all("File", filters={"is_folder": 0, "is_private": is_private,
|
||||
"uploaded_to_dropbox": 0}, fields=['file_url', 'name', 'file_name']):
|
||||
|
|
@ -286,11 +290,11 @@ def get_redirect_url():
|
|||
def get_dropbox_authorize_url():
|
||||
app_details = get_dropbox_settings(redirect_uri=True)
|
||||
dropbox_oauth_flow = dropbox.DropboxOAuth2Flow(
|
||||
app_details["app_key"],
|
||||
app_details["app_secret"],
|
||||
app_details["redirect_uri"],
|
||||
{},
|
||||
"dropbox-auth-csrf-token"
|
||||
consumer_key=app_details["app_key"],
|
||||
redirect_uri=app_details["redirect_uri"],
|
||||
session={},
|
||||
csrf_token_session_key="dropbox-auth-csrf-token",
|
||||
consumer_secret=app_details["app_secret"]
|
||||
)
|
||||
|
||||
auth_url = dropbox_oauth_flow.start()
|
||||
|
|
@ -307,13 +311,13 @@ def dropbox_auth_finish(return_access_token=False):
|
|||
close = '<p class="text-muted">' + _('Please close this window') + '</p>'
|
||||
|
||||
dropbox_oauth_flow = dropbox.DropboxOAuth2Flow(
|
||||
app_details["app_key"],
|
||||
app_details["app_secret"],
|
||||
app_details["redirect_uri"],
|
||||
{
|
||||
consumer_key=app_details["app_key"],
|
||||
redirect_uri=app_details["redirect_uri"],
|
||||
session={
|
||||
'dropbox-auth-csrf-token': callback.state
|
||||
},
|
||||
"dropbox-auth-csrf-token"
|
||||
csrf_token_session_key="dropbox-auth-csrf-token",
|
||||
consumer_secret=app_details["app_secret"]
|
||||
)
|
||||
|
||||
if callback.state or callback.code:
|
||||
|
|
|
|||
|
|
@ -2,22 +2,23 @@
|
|||
# Copyright (c) 2019, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import requests
|
||||
import googleapiclient.discovery
|
||||
import google.oauth2.credentials
|
||||
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import get_request_site_address
|
||||
from googleapiclient.errors import HttpError
|
||||
from frappe.utils.password import set_encrypted_password
|
||||
from frappe.utils import add_days, get_datetime, get_weekdays, now_datetime, add_to_date, get_time_zone
|
||||
from dateutil import parser
|
||||
from datetime import datetime, timedelta
|
||||
from six.moves.urllib.parse import quote
|
||||
from urllib.parse import quote
|
||||
|
||||
import google.oauth2.credentials
|
||||
import requests
|
||||
from dateutil import parser
|
||||
from googleapiclient.discovery import build
|
||||
from googleapiclient.errors import HttpError
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.integrations.doctype.google_settings.google_settings import get_auth_url
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import (add_days, add_to_date, get_datetime,
|
||||
get_request_site_address, get_time_zone, get_weekdays, now_datetime)
|
||||
from frappe.utils.password import set_encrypted_password
|
||||
|
||||
SCOPES = "https://www.googleapis.com/auth/calendar"
|
||||
|
||||
|
|
@ -171,7 +172,12 @@ def get_google_calendar_object(g_calendar):
|
|||
}
|
||||
|
||||
credentials = google.oauth2.credentials.Credentials(**credentials_dict)
|
||||
google_calendar = googleapiclient.discovery.build("calendar", "v3", credentials=credentials)
|
||||
google_calendar = build(
|
||||
serviceName="calendar",
|
||||
version="v3",
|
||||
credentials=credentials,
|
||||
static_discovery=False
|
||||
)
|
||||
|
||||
check_google_calendar(account, google_calendar)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,17 +2,17 @@
|
|||
# Copyright (c) 2019, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import requests
|
||||
import googleapiclient.discovery
|
||||
import google.oauth2.credentials
|
||||
|
||||
from frappe.model.document import Document
|
||||
from frappe import _
|
||||
import google.oauth2.credentials
|
||||
import requests
|
||||
from googleapiclient.discovery import build
|
||||
from googleapiclient.errors import HttpError
|
||||
from frappe.utils import get_request_site_address
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.integrations.doctype.google_settings.google_settings import get_auth_url
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import get_request_site_address
|
||||
|
||||
SCOPES = "https://www.googleapis.com/auth/contacts"
|
||||
|
||||
|
|
@ -118,7 +118,12 @@ def get_google_contacts_object(g_contact):
|
|||
}
|
||||
|
||||
credentials = google.oauth2.credentials.Credentials(**credentials_dict)
|
||||
google_contacts = googleapiclient.discovery.build("people", "v1", credentials=credentials)
|
||||
google_contacts = build(
|
||||
serviceName="people",
|
||||
version="v1",
|
||||
credentials=credentials,
|
||||
static_discovery=False
|
||||
)
|
||||
|
||||
return google_contacts, account
|
||||
|
||||
|
|
|
|||
|
|
@ -2,27 +2,29 @@
|
|||
# Copyright (c) 2019, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import requests
|
||||
import googleapiclient.discovery
|
||||
import google.oauth2.credentials
|
||||
import os
|
||||
from urllib.parse import quote
|
||||
|
||||
from frappe import _
|
||||
from googleapiclient.errors import HttpError
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import get_request_site_address
|
||||
from frappe.utils.background_jobs import enqueue
|
||||
from six.moves.urllib.parse import quote
|
||||
import google.oauth2.credentials
|
||||
import requests
|
||||
from apiclient.http import MediaFileUpload
|
||||
from frappe.utils import get_backups_path, get_bench_path
|
||||
from frappe.utils.backups import new_backup
|
||||
from googleapiclient.discovery import build
|
||||
from googleapiclient.errors import HttpError
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.integrations.doctype.google_settings.google_settings import get_auth_url
|
||||
from frappe.integrations.offsite_backup_utils import get_latest_backup_file, send_email, validate_file_size
|
||||
from frappe.integrations.offsite_backup_utils import (get_latest_backup_file,
|
||||
send_email, validate_file_size)
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import (get_backups_path, get_bench_path,
|
||||
get_request_site_address)
|
||||
from frappe.utils.background_jobs import enqueue
|
||||
from frappe.utils.backups import new_backup
|
||||
|
||||
SCOPES = "https://www.googleapis.com/auth/drive"
|
||||
|
||||
|
||||
class GoogleDrive(Document):
|
||||
|
||||
def validate(self):
|
||||
|
|
@ -126,7 +128,12 @@ def get_google_drive_object():
|
|||
}
|
||||
|
||||
credentials = google.oauth2.credentials.Credentials(**credentials_dict)
|
||||
google_drive = googleapiclient.discovery.build("drive", "v3", credentials=credentials)
|
||||
google_drive = build(
|
||||
serviceName="drive",
|
||||
version="v3",
|
||||
credentials=credentials,
|
||||
static_discovery=False
|
||||
)
|
||||
|
||||
return google_drive, account
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# MIT License. See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import re
|
||||
from io import BytesIO
|
||||
|
||||
import openpyxl
|
||||
import xlrd
|
||||
import re
|
||||
from openpyxl.styles import Font
|
||||
from openpyxl import load_workbook
|
||||
from openpyxl.styles import Font
|
||||
from openpyxl.utils import get_column_letter
|
||||
from six import BytesIO, string_types
|
||||
|
||||
import frappe
|
||||
|
||||
ILLEGAL_CHARACTERS_RE = re.compile(r'[\000-\010]|[\013-\014]|[\016-\037]')
|
||||
|
||||
|
||||
# return xlsx file object
|
||||
def make_xlsx(data, sheet_name, wb=None, column_widths=None):
|
||||
column_widths = column_widths or []
|
||||
|
|
@ -31,12 +32,12 @@ def make_xlsx(data, sheet_name, wb=None, column_widths=None):
|
|||
for row in data:
|
||||
clean_row = []
|
||||
for item in row:
|
||||
if isinstance(item, string_types) and (sheet_name not in ['Data Import Template', 'Data Export']):
|
||||
if isinstance(item, str) and (sheet_name not in ['Data Import Template', 'Data Export']):
|
||||
value = handle_html(item)
|
||||
else:
|
||||
value = item
|
||||
|
||||
if isinstance(item, string_types) and next(ILLEGAL_CHARACTERS_RE.finditer(value), None):
|
||||
if isinstance(item, str) and next(ILLEGAL_CHARACTERS_RE.finditer(value), None):
|
||||
# Remove illegal characters from the string
|
||||
value = re.sub(ILLEGAL_CHARACTERS_RE, '', value)
|
||||
|
||||
|
|
@ -80,12 +81,12 @@ def handle_html(data):
|
|||
|
||||
return value
|
||||
|
||||
|
||||
def read_xlsx_file_from_attached_file(file_url=None, fcontent=None, filepath=None):
|
||||
if file_url:
|
||||
_file = frappe.get_doc("File", {"file_url": file_url})
|
||||
filename = _file.get_full_path()
|
||||
elif fcontent:
|
||||
from io import BytesIO
|
||||
filename = BytesIO(fcontent)
|
||||
elif filepath:
|
||||
filename = filepath
|
||||
|
|
@ -102,6 +103,7 @@ def read_xlsx_file_from_attached_file(file_url=None, fcontent=None, filepath=Non
|
|||
rows.append(tmp_list)
|
||||
return rows
|
||||
|
||||
|
||||
def read_xls_file_from_attached_file(content):
|
||||
book = xlrd.open_workbook(file_contents=content)
|
||||
sheets = book.sheets()
|
||||
|
|
@ -111,6 +113,7 @@ def read_xls_file_from_attached_file(content):
|
|||
rows.append(sheet.row_values(i))
|
||||
return rows
|
||||
|
||||
|
||||
def build_xlsx_response(data, filename):
|
||||
xlsx_file = make_xlsx(data, filename)
|
||||
# write out response as a xlsx type
|
||||
|
|
|
|||
|
|
@ -2,17 +2,18 @@
|
|||
# Copyright (c) 2020, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import requests
|
||||
import googleapiclient.discovery
|
||||
import google.oauth2.credentials
|
||||
|
||||
from frappe import _
|
||||
from urllib.parse import quote
|
||||
|
||||
import google.oauth2.credentials
|
||||
import requests
|
||||
from googleapiclient.discovery import build
|
||||
from googleapiclient.errors import HttpError
|
||||
from frappe.utils import get_request_site_address
|
||||
from six.moves.urllib.parse import quote
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.integrations.doctype.google_settings.google_settings import get_auth_url
|
||||
from frappe.utils import get_request_site_address
|
||||
|
||||
SCOPES = "https://www.googleapis.com/auth/indexing"
|
||||
|
||||
|
|
@ -82,7 +83,12 @@ def get_google_indexing_object():
|
|||
}
|
||||
|
||||
credentials = google.oauth2.credentials.Credentials(**credentials_dict)
|
||||
google_indexing = googleapiclient.discovery.build("indexing", "v3", credentials=credentials)
|
||||
google_indexing = build(
|
||||
serviceName="indexing",
|
||||
version="v3",
|
||||
credentials=credentials,
|
||||
static_discovery=False
|
||||
)
|
||||
|
||||
return google_indexing
|
||||
|
||||
|
|
|
|||
152
requirements.txt
152
requirements.txt
|
|
@ -1,79 +1,79 @@
|
|||
Babel==2.6.0
|
||||
beautifulsoup4==4.8.2
|
||||
bleach-whitelist==0.0.10
|
||||
bleach==3.3.0
|
||||
boto3==1.10.18
|
||||
braintree==3.57.1
|
||||
chardet==3.0.4
|
||||
Click==7.0
|
||||
coverage==4.5.4
|
||||
croniter==0.3.31
|
||||
cryptography==3.3.2
|
||||
dropbox==9.1.0
|
||||
email-reply-parser==0.5.9
|
||||
Faker==2.0.4
|
||||
Babel~=2.9.0
|
||||
beautifulsoup4~=4.9.3
|
||||
bleach-whitelist~=0.0.11
|
||||
bleach~=3.3.0
|
||||
boto3~=1.17.48
|
||||
braintree~=4.8.0
|
||||
chardet~=4.0.0
|
||||
Click~=7.1.2
|
||||
coverage~=5.5
|
||||
croniter~=1.0.11
|
||||
cryptography~=3.4.7
|
||||
dropbox~=11.6.0
|
||||
email-reply-parser~=0.5.12
|
||||
Faker~=8.1.0
|
||||
future==0.18.2
|
||||
gitdb2==2.0.6;python_version<'3.4'
|
||||
GitPython==2.1.15
|
||||
git-url-parse==1.2.2
|
||||
google-api-python-client==1.9.3
|
||||
google-auth-httplib2==0.0.3
|
||||
google-auth-oauthlib==0.4.1
|
||||
google-auth==1.18.0
|
||||
googlemaps==3.1.1
|
||||
gunicorn==19.10.0
|
||||
html2text==2016.9.19
|
||||
html5lib==1.0.1
|
||||
ipython==7.14.0
|
||||
jedi==0.17.2 # not directly required. Pinned to fix upstream issue with ipython.
|
||||
Jinja2==2.11.3
|
||||
ldap3==2.7
|
||||
markdown2==2.4.0
|
||||
git-url-parse~=1.2.2
|
||||
gitdb~=4.0.7
|
||||
GitPython~=3.1.14
|
||||
google-api-python-client~=2.2.0
|
||||
google-auth-httplib2~=0.1.0
|
||||
google-auth-oauthlib~=0.4.4
|
||||
google-auth~=1.28.1
|
||||
googlemaps~=4.4.5
|
||||
gunicorn~=20.1.0
|
||||
html2text==2020.1.16
|
||||
html5lib~=1.1
|
||||
ipython~=7.16.1
|
||||
jedi==0.17.2 # not directly required. Pinned to fix upstream IPython issue (https://github.com/ipython/ipython/issues/12740)
|
||||
Jinja2~=2.11.3
|
||||
ldap3~=2.9
|
||||
markdown2~=2.4.0
|
||||
maxminddb-geolite2==2018.703
|
||||
ndg-httpsclient==0.5.1
|
||||
num2words==0.5.10
|
||||
oauthlib==3.1.0
|
||||
openpyxl==2.6.4
|
||||
passlib==1.7.3
|
||||
pdfkit==0.6.1
|
||||
Pillow>=8.0.0
|
||||
premailer==3.6.1
|
||||
psutil==5.7.2
|
||||
psycopg2-binary==2.8.4
|
||||
pyasn1==0.4.8
|
||||
PyJWT==1.7.1
|
||||
PyMySQL==0.9.3
|
||||
pyngrok==4.1.6
|
||||
pyOpenSSL==19.1.0
|
||||
pyotp==2.3.0
|
||||
PyPDF2==1.26.0
|
||||
pypng==0.0.20
|
||||
PyQRCode==1.2.1
|
||||
python-dateutil==2.8.1
|
||||
pytz==2019.3
|
||||
PyYAML==5.4
|
||||
rauth==0.7.3
|
||||
redis==3.5.3
|
||||
requests-oauthlib==1.3.0
|
||||
requests==2.23.0
|
||||
RestrictedPython==5.0
|
||||
rq>=1.1.0
|
||||
schedule==0.6.0
|
||||
semantic-version==2.8.4
|
||||
simple-chalk==0.1.0
|
||||
six==1.14.0
|
||||
sqlparse==0.2.4
|
||||
stripe==2.40.0
|
||||
terminaltables==3.1.0
|
||||
unittest-xml-reporting==2.5.2
|
||||
urllib3==1.25.9
|
||||
watchdog==0.8.0
|
||||
Werkzeug==0.16.1
|
||||
Whoosh==2.7.4
|
||||
xlrd==1.2.0
|
||||
zxcvbn-python==4.4.24
|
||||
pycryptodome==3.9.8
|
||||
paytmchecksum==1.7.0
|
||||
wrapt==1.10.11
|
||||
razorpay==1.2.0
|
||||
ndg-httpsclient~=0.5.1
|
||||
num2words~=0.5.10
|
||||
oauthlib~=3.1.0
|
||||
openpyxl~=3.0.7
|
||||
passlib~=1.7.4
|
||||
paytmchecksum~=1.7.0
|
||||
pdfkit~=0.6.1
|
||||
Pillow~=8.2.0
|
||||
premailer~=3.7.0
|
||||
psutil~=5.8.0
|
||||
psycopg2-binary~=2.8.6
|
||||
pyasn1~=0.4.8
|
||||
pycryptodome~=3.10.1
|
||||
PyJWT~=1.7.1
|
||||
PyMySQL~=1.0.2
|
||||
pyngrok~=5.0.5
|
||||
pyOpenSSL~=20.0.1
|
||||
pyotp~=2.6.0
|
||||
PyPDF2~=1.26.0
|
||||
pypng~=0.0.20
|
||||
PyQRCode~=1.2.1
|
||||
python-dateutil~=2.8.1
|
||||
pytz==2021.1
|
||||
PyYAML~=5.4.1
|
||||
rauth~=0.7.3
|
||||
razorpay~=1.2.0
|
||||
redis~=3.5.3
|
||||
requests-oauthlib~=1.3.0
|
||||
requests~=2.25.1
|
||||
RestrictedPython~=5.1
|
||||
rq~=1.8.0
|
||||
rsa>=4.1 # not directly required, pinned by Snyk to avoid a vulnerability
|
||||
schedule~=1.1.0
|
||||
semantic-version~=2.8.5
|
||||
simple-chalk~=0.1.0
|
||||
six~=1.15.0
|
||||
sqlparse~=0.4.1
|
||||
stripe~=2.56.0
|
||||
terminaltables~=3.1.0
|
||||
unittest-xml-reporting~=3.0.4
|
||||
urllib3~=1.26.4
|
||||
watchdog~=2.0.2
|
||||
Werkzeug~=0.16.1
|
||||
Whoosh~=2.7.4
|
||||
wrapt~=1.12.1
|
||||
xlrd~=2.0.1
|
||||
zxcvbn-python~=4.4.24
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue