diff --git a/CHANGELOG.md b/CHANGELOG.md index 794d0fbaa03..a98ed74c954 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,6 +76,9 @@ All notable, unreleased changes to this project will be documented in this file. - Add attributes validation while creating/updating a product's variant - #6269 by @GrzegorzDerdak - Add metadata to page model - #6292 by @dominik-zeglen - Fix for unnecesary attributes validation while updating simple product - #6300 by @GrzegorzDerdak +- Include order line total price to webhook payload - #6354 by @korycins +- Fix for fulfilling an order when product quantity equals allocated quantity - #6333 by @GrzegorzDerdak +- Fix for the ability to filter products on collection - #6363 by @GrzegorzDerdak ## 2.10.2 diff --git a/locale/ar/LC_MESSAGES/django.mo b/locale/ar/LC_MESSAGES/django.mo index 560821499b6..339270f0c95 100644 Binary files a/locale/ar/LC_MESSAGES/django.mo and b/locale/ar/LC_MESSAGES/django.mo differ diff --git a/locale/az/LC_MESSAGES/django.mo b/locale/az/LC_MESSAGES/django.mo index e1c7c0af228..b606e482c1e 100644 Binary files a/locale/az/LC_MESSAGES/django.mo and b/locale/az/LC_MESSAGES/django.mo differ diff --git a/locale/bg/LC_MESSAGES/django.mo b/locale/bg/LC_MESSAGES/django.mo index 71108569465..d6dbe0b4350 100644 Binary files a/locale/bg/LC_MESSAGES/django.mo and b/locale/bg/LC_MESSAGES/django.mo differ diff --git a/locale/bn/LC_MESSAGES/django.mo b/locale/bn/LC_MESSAGES/django.mo index 05f167161cf..fe279891229 100644 Binary files a/locale/bn/LC_MESSAGES/django.mo and b/locale/bn/LC_MESSAGES/django.mo differ diff --git a/locale/ca/LC_MESSAGES/django.mo b/locale/ca/LC_MESSAGES/django.mo index d681ec82004..7ce5c129aaa 100644 Binary files a/locale/ca/LC_MESSAGES/django.mo and b/locale/ca/LC_MESSAGES/django.mo differ diff --git a/locale/cs/LC_MESSAGES/django.mo b/locale/cs/LC_MESSAGES/django.mo index b13d905788b..f5d4979751a 100644 Binary files a/locale/cs/LC_MESSAGES/django.mo and b/locale/cs/LC_MESSAGES/django.mo differ diff --git a/locale/da/LC_MESSAGES/django.mo b/locale/da/LC_MESSAGES/django.mo index df3ed6cde7b..86597452d80 100644 Binary files a/locale/da/LC_MESSAGES/django.mo and b/locale/da/LC_MESSAGES/django.mo differ diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 0a8e8ae8b8d..08b3f4e5c7a 100644 Binary files a/locale/de/LC_MESSAGES/django.mo and b/locale/de/LC_MESSAGES/django.mo differ diff --git a/locale/el/LC_MESSAGES/django.mo b/locale/el/LC_MESSAGES/django.mo index 867e4ac23e6..0fee436f28b 100644 Binary files a/locale/el/LC_MESSAGES/django.mo and b/locale/el/LC_MESSAGES/django.mo differ diff --git a/locale/en/LC_MESSAGES/django.mo b/locale/en/LC_MESSAGES/django.mo index 66dcc3a08d1..ca95654924b 100644 Binary files a/locale/en/LC_MESSAGES/django.mo and b/locale/en/LC_MESSAGES/django.mo differ diff --git a/locale/es/LC_MESSAGES/django.mo b/locale/es/LC_MESSAGES/django.mo index 7dc5afa1820..4f29ca4fcf3 100644 Binary files a/locale/es/LC_MESSAGES/django.mo and b/locale/es/LC_MESSAGES/django.mo differ diff --git a/locale/es_CO/LC_MESSAGES/django.mo b/locale/es_CO/LC_MESSAGES/django.mo index c455f8c5278..71e45e743d3 100644 Binary files a/locale/es_CO/LC_MESSAGES/django.mo and b/locale/es_CO/LC_MESSAGES/django.mo differ diff --git a/locale/et/LC_MESSAGES/django.mo b/locale/et/LC_MESSAGES/django.mo index fc374e1b00b..ea9864eae85 100644 Binary files a/locale/et/LC_MESSAGES/django.mo and b/locale/et/LC_MESSAGES/django.mo differ diff --git a/locale/et/LC_MESSAGES/django.po b/locale/et/LC_MESSAGES/django.po index 15cbb3cb1b0..a3b3ede60e7 100644 --- a/locale/et/LC_MESSAGES/django.po +++ b/locale/et/LC_MESSAGES/django.po @@ -7,15 +7,17 @@ # Carmel Vaher , 2020 # Henri Tamvere , 2020 # Erlend Eelmets , 2020 +# Patryk Zawadzki , 2020 +# Marcin Gębala , 2020 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: master\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-11 12:15+0000\n" +"POT-Creation-Date: 2020-10-23 07:04+0000\n" "PO-Revision-Date: 2017-02-08 11:00+0000\n" -"Last-Translator: Erlend Eelmets , 2020\n" +"Last-Translator: Marcin Gębala , 2020\n" "Language-Team: Estonian (https://www.transifex.com/mirumee/teams/34782/et/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -27,7 +29,7 @@ msgstr "" #, python-format msgctxt "Address data" msgid "%(first_name)s %(last_name)s" -msgstr "% (eesnimi) s% (perenimi) s" +msgstr "%(first_name)s %(last_name)s" #: saleor/account/templatetags/i18n_address_tags.py:16 #, python-format @@ -36,56 +38,60 @@ msgid "" "%(street_address_1)s\n" "%(street_address_2)s" msgstr "" -"% (tänava_adress_1) s \n" -"% (tänava_adress_2) s%(street_address_1)s\n" +"%(street_address_1)s\n" "%(street_address_2)s" -#: templates/invoices/invoice.html:218 +#: templates/invoices/invoice.html:210 msgctxt "Invoice PDF header" msgid "INVOICE INFORMATION" msgstr "ARVETE TEAVE" -#: templates/invoices/invoice.html:221 +#: templates/invoices/invoice.html:213 msgctxt "Invoice PDF header: Invoice number" msgid "Invoice number:" msgstr "Arve number:" -#: templates/invoices/invoice.html:227 +#: templates/invoices/invoice.html:219 msgctxt "Invoice PDF header: order number" msgid "Order:" msgstr "Tellimus:" -#: templates/invoices/invoice.html:233 +#: templates/invoices/invoice.html:225 msgctxt "Invoice PDF header" msgid "Date:" msgstr "Kuupäev:" -#: templates/invoices/invoice.html:239 +#: templates/invoices/invoice.html:231 msgctxt "Invoice PDF amount (price)" msgid "Amount:" msgstr "Summa:" -#: templates/invoices/invoice.html:248 +#: templates/invoices/invoice.html:240 msgctxt "Invoice PDF" msgid "BILLING ADDRESS" msgstr "ARVE AADRESS" -#: templates/invoices/invoice.html:277 +#: templates/invoices/invoice.html:269 msgctxt "Invoice PDF" msgid "SHIPMENT ADDRESS" msgstr "SAADETE AADRESS" -#: templates/invoices/invoice.html:308 +#: templates/invoices/invoice.html:300 msgctxt "Invoice PDF" msgid "PAYMENT METHOD" msgstr "MAKSEVIIS" -#: templates/invoices/invoice.html:316 +#: templates/invoices/invoice.html:306 +msgctxt "Invoice PDF: Payment method value" +msgid "Unpaid" +msgstr "Maksmata" + +#: templates/invoices/invoice.html:314 msgctxt "Invoice PDF" msgid "SHIPMENT METHOD" msgstr "SAATMISVIIS" -#: templates/invoices/invoice.html:326 +#: templates/invoices/invoice.html:324 msgctxt "Invoice PDF table header" msgid "ITEMS ORDERED" msgstr "TELLITUD PUNKTID" @@ -165,7 +171,7 @@ msgid "" "Please click the link below to do so and log into your account.\n" msgstr "" "\n" -"% (Saidi_nimi) s sisselogimiseks peate kõigepealt kinnitama oma e-posti aadressi.\n" +"%(site_name)s sisselogimiseks peate kõigepealt kinnitama oma e-posti aadressi.\n" "Selleks klõpsake alloleval lingil ja logige sisse oma kontole.\n" #: templates/templated_email/account/email_changed_notification.email:4 @@ -326,7 +332,7 @@ msgid "" msgstr "" "\n" "Makseandmete nägemiseks külastage palun: \n" -"% (order_details_url) s \n" +"%(order_details_url)s \n" #: templates/templated_email/order/confirm_order.email:25 #: templates/templated_email/order/staff_confirm_order.email:25 @@ -406,7 +412,7 @@ msgstr "Saatmine pole vajalik" #, python-format msgctxt "Order cancel e-mail subject" msgid "Order %(order)s canceled" -msgstr "Tellimus% (tellimus) on tühistatud" +msgstr "Tellimus %(order)s on tühistatud" #: templates/templated_email/order/order_cancel.email:11 msgctxt "Order cancel e-mail text" @@ -421,7 +427,7 @@ msgstr "" #, python-format msgctxt "Order refund e-mail subject" msgid "Order %(order)s refunded" -msgstr "Tellimus% (tellimus) tagastati" +msgstr "Tellimus %(order)s tagastati" #: templates/templated_email/order/order_refund.email:11 #, python-format @@ -504,7 +510,7 @@ msgstr "See on automaatselt genereeritud e-kiri, palun ärge vastake." #, python-format msgctxt "Base email footer" msgid "Sincerely, %(site_name)s" -msgstr "Lugupidamisega% (saidi_nimi) s" +msgstr "Lugupidamisega %(site_name)s" #: templates/templated_email/shared/_header.email:2 #: templates/templated_email/source/account_delete.mjml:13 @@ -549,7 +555,7 @@ msgid "" "In order to log into %(site_name)s, you have to confirm your email address " "first. Please click the link below to do so and log into your account." msgstr "" -"% (Saidi_nimi) s sisselogimiseks peate kinnitama oma e-posti " +"%(site_name)s sisselogimiseks peate kinnitama oma e-posti " "aadressikõigepealt. Selleks klõpsake palun allolevat linki ja logige sisse " "oma kontole." @@ -765,7 +771,8 @@ msgid "" " %(order_details_url)s" msgstr "" "Keegi esitas teie poes uue tellimuse. Tellimuse üksikasjade nägemiseks " -"külastage palun:%(order_details_url)s" #: templates/templated_email/source/update_fulfillment.mjml:16 msgctxt "Fulfillment update email text" diff --git a/locale/fa/LC_MESSAGES/django.mo b/locale/fa/LC_MESSAGES/django.mo index 12abc558d48..1c765d4e58c 100644 Binary files a/locale/fa/LC_MESSAGES/django.mo and b/locale/fa/LC_MESSAGES/django.mo differ diff --git a/locale/fi/LC_MESSAGES/django.mo b/locale/fi/LC_MESSAGES/django.mo index 08b7295966c..86b403d2dbe 100644 Binary files a/locale/fi/LC_MESSAGES/django.mo and b/locale/fi/LC_MESSAGES/django.mo differ diff --git a/locale/fr/LC_MESSAGES/django.mo b/locale/fr/LC_MESSAGES/django.mo index c09d7bf05cb..28fef90f7d7 100644 Binary files a/locale/fr/LC_MESSAGES/django.mo and b/locale/fr/LC_MESSAGES/django.mo differ diff --git a/locale/hi/LC_MESSAGES/django.mo b/locale/hi/LC_MESSAGES/django.mo index e1ff35a35c8..5c1c98cfd5d 100644 Binary files a/locale/hi/LC_MESSAGES/django.mo and b/locale/hi/LC_MESSAGES/django.mo differ diff --git a/locale/hu/LC_MESSAGES/django.mo b/locale/hu/LC_MESSAGES/django.mo index 6e1858a92b2..d132f987f8d 100644 Binary files a/locale/hu/LC_MESSAGES/django.mo and b/locale/hu/LC_MESSAGES/django.mo differ diff --git a/locale/hy/LC_MESSAGES/django.mo b/locale/hy/LC_MESSAGES/django.mo index 60cfd897218..470b316a3dc 100644 Binary files a/locale/hy/LC_MESSAGES/django.mo and b/locale/hy/LC_MESSAGES/django.mo differ diff --git a/locale/id/LC_MESSAGES/django.mo b/locale/id/LC_MESSAGES/django.mo index e8757ea3852..a12f2686a02 100644 Binary files a/locale/id/LC_MESSAGES/django.mo and b/locale/id/LC_MESSAGES/django.mo differ diff --git a/locale/is/LC_MESSAGES/django.mo b/locale/is/LC_MESSAGES/django.mo index 74a5ea7691b..cc8204167c0 100644 Binary files a/locale/is/LC_MESSAGES/django.mo and b/locale/is/LC_MESSAGES/django.mo differ diff --git a/locale/it/LC_MESSAGES/django.mo b/locale/it/LC_MESSAGES/django.mo index e312745680b..f37fc114b52 100644 Binary files a/locale/it/LC_MESSAGES/django.mo and b/locale/it/LC_MESSAGES/django.mo differ diff --git a/locale/ja/LC_MESSAGES/django.mo b/locale/ja/LC_MESSAGES/django.mo index 3f4e0c7e305..235d260aab1 100644 Binary files a/locale/ja/LC_MESSAGES/django.mo and b/locale/ja/LC_MESSAGES/django.mo differ diff --git a/locale/ka/LC_MESSAGES/django.mo b/locale/ka/LC_MESSAGES/django.mo new file mode 100644 index 00000000000..8233cf95359 Binary files /dev/null and b/locale/ka/LC_MESSAGES/django.mo differ diff --git a/locale/ka/LC_MESSAGES/django.po b/locale/ka/LC_MESSAGES/django.po new file mode 100644 index 00000000000..f593aa80fbb --- /dev/null +++ b/locale/ka/LC_MESSAGES/django.po @@ -0,0 +1,738 @@ +# Saleor +# Copyright (C) 2017 Mirumee Software +# This file is distributed under the same license as the Saleor package. +# Mirumee Software , 2017. +# +# Translators: +# Vakh Zukhbaia , 2020 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: master\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-10-23 07:04+0000\n" +"PO-Revision-Date: 2017-02-08 11:00+0000\n" +"Last-Translator: Vakh Zukhbaia , 2020\n" +"Language-Team: Georgian (https://www.transifex.com/mirumee/teams/34782/ka/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ka\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: saleor/account/templatetags/i18n_address_tags.py:12 +#, python-format +msgctxt "Address data" +msgid "%(first_name)s %(last_name)s" +msgstr "%(first_name)s %(last_name)s" + +#: saleor/account/templatetags/i18n_address_tags.py:16 +#, python-format +msgctxt "Address data" +msgid "" +"%(street_address_1)s\n" +"%(street_address_2)s" +msgstr "" +"%(street_address_1)s\n" +"%(street_address_2)s" + +#: templates/invoices/invoice.html:210 +msgctxt "Invoice PDF header" +msgid "INVOICE INFORMATION" +msgstr "ინვოისი" + +#: templates/invoices/invoice.html:213 +msgctxt "Invoice PDF header: Invoice number" +msgid "Invoice number:" +msgstr "ინვოისის ნომერი:" + +#: templates/invoices/invoice.html:219 +msgctxt "Invoice PDF header: order number" +msgid "Order:" +msgstr "შეკვეთა:" + +#: templates/invoices/invoice.html:225 +msgctxt "Invoice PDF header" +msgid "Date:" +msgstr "თარიღი:" + +#: templates/invoices/invoice.html:231 +msgctxt "Invoice PDF amount (price)" +msgid "Amount:" +msgstr "ჯამი:" + +#: templates/invoices/invoice.html:240 +msgctxt "Invoice PDF" +msgid "BILLING ADDRESS" +msgstr "ბილინგ მისამართი:" + +#: templates/invoices/invoice.html:269 +msgctxt "Invoice PDF" +msgid "SHIPMENT ADDRESS" +msgstr "მიწოდების მისამართი" + +#: templates/invoices/invoice.html:300 +msgctxt "Invoice PDF" +msgid "PAYMENT METHOD" +msgstr "გადახდის მეთოდი" + +#: templates/invoices/invoice.html:306 +msgctxt "Invoice PDF: Payment method value" +msgid "Unpaid" +msgstr "გადაუხდელი" + +#: templates/invoices/invoice.html:314 +msgctxt "Invoice PDF" +msgid "SHIPMENT METHOD" +msgstr "მიწოდების მეთოდი" + +#: templates/invoices/invoice.html:324 +msgctxt "Invoice PDF table header" +msgid "ITEMS ORDERED" +msgstr "ნივთი/ები შეკვეთილია" + +#: templates/invoices/invoice_products_table.html:7 +msgctxt "Invoice PDF table" +msgid "Products" +msgstr "პროდუქცია" + +#: templates/invoices/invoice_products_table.html:10 +msgctxt "Invoice PDF table" +msgid "Price" +msgstr "ფასი" + +#: templates/invoices/invoice_products_table.html:13 +msgctxt "Invoice PDF table" +msgid "Quantity" +msgstr "რაოდენობა" + +#: templates/invoices/invoice_products_table.html:16 +msgctxt "Invoice PDF table" +msgid "Total Price" +msgstr "ჯამური ფასი" + +#: templates/invoices/invoice_summary_table.html:8 +msgctxt "Invoice PDF summary" +msgid "Subtotal" +msgstr "ქვეტოტალი" + +#: templates/invoices/invoice_summary_table.html:21 +msgctxt "Invoice PDF summary" +msgid "Delivery Cost" +msgstr "მიწოდების/ტრანსპორტირების საფასური" + +#: templates/invoices/invoice_summary_table.html:34 +msgctxt "Invoice PDF summary" +msgid "Tax" +msgstr "დღგ" + +#: templates/invoices/invoice_summary_table.html:47 +msgctxt "Invoice PDF summary" +msgid "Grand Total" +msgstr "ჯამი" + +#: templates/templated_email/account/account_delete.email:4 +msgctxt "Account delete reset e-mail subject" +msgid "Delete your account" +msgstr "ანგარიშის წაშლა" + +#: templates/templated_email/account/account_delete.email:9 +#, python-format +msgctxt "Account delete reset e-mail text" +msgid "" +"\n" +"You're receiving this e-mail because you or someone else has requested a deletion of your user account at %(site_name)s.\n" +"Click the link below to delete your account.\n" +"\n" +"Please note that this action is permanent and cannot be reversed.\n" +msgstr "" +"\n" +"გაცნობებთ რომ თქვენს მიერ მოტხოვნით იგეგმება თქვენი მომხმარებლის ანგარიშის წაშლა %(site_name)s\n" +"თქვენი ანგარიშის წასაშლელად გადადით ქვემოთ მოცემულ ბმულზე\n" +"გთხოვთ გაითვალისწინოთ, რომ ეს მოქმედება მუდმივია და მისი შეცვლა შეუძლებელია\n" + +#: templates/templated_email/account/confirm.email:4 +msgctxt "Account confirmation e-mail subject" +msgid "Account confirmation e-mail" +msgstr "ანგარიშის დადასტურების ელ.ფოსტა" + +#: templates/templated_email/account/confirm.email:9 +#, python-format +msgctxt "Account confirmation e-mail text" +msgid "" +"\n" +"In order to log into %(site_name)s, you have to confirm your email address first.\n" +"Please click the link below to do so and log into your account.\n" +msgstr "" +"\n" +"იმ შემთხვევაში რომ შეხვიდეთ %(site_name)s, ჯერ უნდა დაადასტუროთ თქვენი ელ.ფოსტის მისამართი.\n" +"ამისათვის გთხოვთ, გადადით ქვემოთ მოცემულ ბმულზე და შეხვიდეთ თქვენს ანგარიშში.\n" + +#: templates/templated_email/account/email_changed_notification.email:4 +#: templates/templated_email/account/request_email_change.email:4 +msgctxt "Email change e-mail subject" +msgid "Email change e-mail" +msgstr "ელ. ფოსთის შეცვლა" + +#: templates/templated_email/account/email_changed_notification.email:9 +#, python-format +msgctxt "Email change e-mail text" +msgid "" +"\n" +"\n" +"You're receiving this e-mail because you or someone else has changed email for your user account at %(site_name)s.\n" +"If you didn't request this change, please contact the administrator.\n" +msgstr "" +"\n" +"\n" +"გაცნობებთ რომ თქვენს ანგარიშზე (%(site_name)s) მოხდა ელ.ფოსტის შეცვლა.\n" +"თუ თქვენ არ მოითხოვეთ ეს ცვლილება, გთხოვთ დაგვიკავშრდით.\n" + +#: templates/templated_email/account/password_reset.email:4 +msgctxt "Password reset e-mail subject" +msgid "Password reset e-mail" +msgstr "პაროლის აღდგენა ელ.ფოსტა" + +#: templates/templated_email/account/password_reset.email:9 +#, python-format +msgctxt "Password reset e-mail text" +msgid "" +"\n" +"You're receiving this e-mail because you or someone else has requested a password for your user account at %(site_name)s.\n" +"It can be safely ignored if you did not request a password reset. Click the link below to reset your password.\n" +msgstr "" +"\n" +"გახნობებთ რომ თვენი მოთხოვნით ხდება პაროლის შეცვლა ანგარიშზე %(site_name)s.\n" +"დააჭირეთ ქვემოთ მოცემულ ბმულს თქვენი ახალი პაროლის შესაყვანად.\n" + +#: templates/templated_email/account/request_email_change.email:9 +#, python-format +msgctxt "Email change e-mail text" +msgid "" +"\n" +"\n" +"You're receiving this e-mail because you or someone else has requested an email change for your user account at %(site_name)s.\n" +"It can be safely ignored if you did not request an email change. Click the link below to confirm new email address.\n" +msgstr "" + +#: templates/templated_email/csv/export_failed.email:4 +#: templates/templated_email/csv/export_products_file.email:4 +msgctxt "Export products e-mail subject" +msgid "Export products data" +msgstr "პროდუქციის მონაცემების ექსპორტი" + +#: templates/templated_email/csv/export_failed.email:10 +msgctxt "Export products e-mail text" +msgid "" +"Sorry, we cannot finish product export, some unexpected errors occurred. " +"Please try again." +msgstr "" +"უკაცრავად, პროდუქტის ექსპორტი ვერ მოხერხდა, მოხდა მოულოდნელი შეცდომები. " +"გთხოვთ კიდევ სცადეთ." + +#: templates/templated_email/csv/export_products_file.email:10 +#, python-format +msgctxt "Export products e-mail text" +msgid "Your file with products data is ready to download: %(csv_link)s" +msgstr "" +"თქვენი ფაილი პროდუქტების მონაცემებით მზად არის ჩამოსატვირთად:%(csv_link)s" + +#: templates/templated_email/dashboard/customer/set_password.email:2 +#, python-format +msgctxt "Set password for customer e-mail title" +msgid "Hello from %(site_name)s!" +msgstr "მოგესალმებით %(site_name)s -დან!" + +#: templates/templated_email/dashboard/customer/set_password.email:6 +#, python-format +msgctxt "Set password for customer e-mail text" +msgid "" +"\n" +"You're receiving this e-mail because you have to set a password for your customer account at %(site_name)s.\n" +"Click the link below to reset your password.\n" +msgstr "" + +#: templates/templated_email/dashboard/staff/set_password.email:2 +#, python-format +msgctxt "Set password for staff member e-mail title" +msgid "Hello from %(site_name)s!" +msgstr "მოგესალმებით %(site_name)s -დან!" + +#: templates/templated_email/dashboard/staff/set_password.email:6 +#, python-format +msgctxt "Set password for staff member e-mail text" +msgid "" +"\n" +"You're receiving this e-mail because you have to set a password for your staff member account at %(site_name)s.\n" +"Click the link below to reset your password.\n" +msgstr "" + +#: templates/templated_email/order/confirm_fulfillment.email:4 +#, python-format +msgctxt "Fulfillment confirmation email subject" +msgid "Your order %(order)s has been fulfilled" +msgstr "თქვენი შეკვეთა %(order)s შესრულებულია" + +#: templates/templated_email/order/confirm_fulfillment.email:11 +msgctxt "Fulfillment confirmation email text" +msgid "" +"\n" +"Thank you for your order. Below is the list of fulfilled products.\n" +msgstr "" +"\n" +"გმადლობთ შეკვეთისთვის. ქვემოთ მოცემულია შესრულებული პროდუქტების ჩამონათვალი.\n" + +#: templates/templated_email/order/confirm_fulfillment.email:15 +#: templates/templated_email/source/confirm_fulfillment.mjml:25 +#: templates/templated_email/source/update_fulfillment.mjml:25 +#, python-format +msgctxt "Fulfillment confirmation email text" +msgid "You can track your shipment with %(tracking_number)s code." +msgstr "" +"თქვენ შეგიძლიათ თვალყური ადევნოთ თქვენს გადაზიდვას %(tracking_number)s " +"კოდით." + +#: templates/templated_email/order/confirm_order.email:6 +#: templates/templated_email/order/staff_confirm_order.email:6 +#, python-format +msgctxt "Order confirmation e-mail subject" +msgid "Order %(order)s details" +msgstr "შეკვეთს %(order)s დეტალები" + +#: templates/templated_email/order/confirm_order.email:13 +msgctxt "Order confirmation e-mail text" +msgid "" +"\n" +"Thank you for your order. Below is the list of ordered products.\n" +msgstr "" +"\n" +"გმადლობთ შეკვეთისთვის. ქვემოთ მოცემულია შესრულებული პროდუქტების ჩამონათვალი.\n" + +#: templates/templated_email/order/confirm_order.email:17 +#: templates/templated_email/order/staff_confirm_order.email:17 +#, python-format +msgctxt "Order confirmation e-mail payment details" +msgid "" +"\n" +"To see your payment details please visit:\n" +"%(order_details_url)s\n" +msgstr "" +"\n" +"თქვენი გადახდის დეტალების სანახავად ეწვიეთ:\n" +"%(order_details_url)s\n" + +#: templates/templated_email/order/confirm_order.email:25 +#: templates/templated_email/order/staff_confirm_order.email:25 +msgctxt "Order confirmation e-mail table header" +msgid "Order summary" +msgstr "შეკვეთის დეტალები" + +#: templates/templated_email/order/confirm_order.email:26 +#: templates/templated_email/order/staff_confirm_order.email:26 +msgctxt "Order confirmation e-mail table header" +msgid "Subtotal" +msgstr "ქვეტოტალი" + +#: templates/templated_email/order/confirm_order.email:27 +#: templates/templated_email/order/staff_confirm_order.email:27 +msgctxt "Order confirmation e-mail table header" +msgid "Shipping" +msgstr "მიწოდება" + +#: templates/templated_email/order/confirm_order.email:28 +#: templates/templated_email/order/staff_confirm_order.email:28 +msgctxt "Order confirmation e-mail table header" +msgid "Taxes (included)" +msgstr "დღგ (ჩათვლით)" + +#: templates/templated_email/order/confirm_order.email:28 +#: templates/templated_email/order/staff_confirm_order.email:28 +msgctxt "Order confirmation e-mail table header" +msgid "Taxes" +msgstr "დღგ" + +#: templates/templated_email/order/confirm_order.email:29 +#: templates/templated_email/order/staff_confirm_order.email:29 +msgctxt "Order confirmation e-mail table header" +msgid "Discount:" +msgstr "ფასდაკლება:" + +#: templates/templated_email/order/confirm_order.email:30 +#: templates/templated_email/order/staff_confirm_order.email:30 +msgctxt "Order confirmation e-mail table header" +msgid "Total" +msgstr "ჯამი" + +#: templates/templated_email/order/confirm_order.email:32 +#: templates/templated_email/order/staff_confirm_order.email:32 +#: templates/templated_email/source/confirm_order.mjml:35 +#: templates/templated_email/source/staff_confirm_order.mjml:29 +msgctxt "Order confirmation e-mail billing address" +msgid "Billing address" +msgstr "გადახდის მისამართი" + +#: templates/templated_email/order/confirm_order.email:33 +#: templates/templated_email/order/staff_confirm_order.email:33 +#: templates/templated_email/source/confirm_order.mjml:45 +#: templates/templated_email/source/staff_confirm_order.mjml:39 +msgctxt "Order confirmation e-mail text" +msgid "No billing address" +msgstr "გადახდის მისამართის გარაშე" + +#: templates/templated_email/order/confirm_order.email:35 +#: templates/templated_email/order/staff_confirm_order.email:35 +#: templates/templated_email/source/confirm_order.mjml:36 +#: templates/templated_email/source/staff_confirm_order.mjml:30 +msgctxt "Order confirmation e-mail shipping address" +msgid "Shipping address" +msgstr "მიწოდების მისამართი" + +#: templates/templated_email/order/confirm_order.email:36 +#: templates/templated_email/order/staff_confirm_order.email:36 +#: templates/templated_email/source/confirm_order.mjml:52 +#: templates/templated_email/source/staff_confirm_order.mjml:46 +msgctxt "Order confirmation e-mail text" +msgid "No shipping required" +msgstr "მიწოდების მისამართი გარაშე" + +#: templates/templated_email/order/order_cancel.email:4 +#, python-format +msgctxt "Order cancel e-mail subject" +msgid "Order %(order)s canceled" +msgstr "შეკვეთა %(order)s გაუქმებულია" + +#: templates/templated_email/order/order_cancel.email:11 +msgctxt "Order cancel e-mail text" +msgid "" +"\n" +"Your order has been canceled.\n" +msgstr "" +"\n" +"თქვენი შეკვეთა გაუქმებულია.\n" + +#: templates/templated_email/order/order_refund.email:4 +#, python-format +msgctxt "Order refund e-mail subject" +msgid "Order %(order)s refunded" +msgstr "შეკვეთა %(order)s დაბრუნებულია" + +#: templates/templated_email/order/order_refund.email:11 +#, python-format +msgctxt "Order refund e-mail text" +msgid "" +"\n" +"A payment of %(amount)s %(currency)s has been refunded for your order.\n" +msgstr "" +"\n" +"გადხდილი %(amount)s %(currency)s ანაზღაურდა თქვენი შეკვეთისთვის.\n" + +#: templates/templated_email/order/payment/confirm_payment.email:4 +#, python-format +msgctxt "Payment confirmation subject" +msgid "Order %(order)s payment details" +msgstr "შეკვეთა %(order)s გადახდის დეტალები" + +#: templates/templated_email/order/payment/confirm_payment.email:11 +msgctxt "Payment confirmation email text" +msgid "" +"\n" +"Thank you for your payment.\n" +"Your payment was successfully processed.\n" +msgstr "" +"\n" +"მადლობა შეკვეთისთვის.\n" +"თქვენი გადახდა წარმატებით დამუშავდა.\n" + +#: templates/templated_email/order/send_invoice.email:4 +msgctxt "Invoice email subject" +msgid "Invoice" +msgstr "ინვოისი" + +#: templates/templated_email/order/send_invoice.email:9 +#, python-format +msgctxt "Send invoice e-mail text" +msgid "" +"\n" +"In order to download invoice %(number)s, click the link below.\n" +msgstr "" +"\n" +"ინვოისის გადმოსაწერად %(number)s, დააჭირეთ ქვემოთ მოცემულ ბმულს.\n" + +#: templates/templated_email/order/staff_confirm_order.email:13 +msgctxt "Order confirmation staff e-mail text" +msgid "" +"\n" +"Below is the list of ordered products.\n" +msgstr "" +"\n" +"ქვემოთ მოცემულია შეკვეთილი პროდუქტების ჩამონათვალი.\n" + +#: templates/templated_email/order/update_fulfillment.email:4 +#, python-format +msgctxt "Fulfillment update email subject" +msgid "Shipping update for order %(order)s" +msgstr "გადაზიდვის განახლება შეკვეთისთვის %(order)s" + +#: templates/templated_email/order/update_fulfillment.email:11 +msgctxt "Fulfillment update email text" +msgid "" +"\n" +"Your shipping status has been updated. Below is the list of ordered products that have been updated with new tracking number.\n" +msgstr "" +"\n" +"თქვენი გადაზიდვის სტატუსი განახლდა. ქვემოთ მოცემულია შეკვეთილი პროდუქტების ჩამონათვალი, რომლებიც განახლებულია ახალი თვალთვალის ნომრით.\n" + +#: templates/templated_email/order/update_fulfillment.email:15 +#, python-format +msgctxt "Fulfillment update email text" +msgid "" +"You can track your shipment with the following code: %(tracking_number)s." +msgstr "" +"შეგიძლიათ გააგზავნოთ თქვენი გადაზიდვა შემდეგი კოდით: %(tracking_number)s" + +#: templates/templated_email/shared/_footer.email:2 +#: templates/templated_email/source/shared/footer.mjml:4 +msgctxt "Base email text" +msgid "This is an automatically generated e-mail, please do not reply." +msgstr "ეს არის ავტომატურად წარმოქმნილი ელ.წერილი, ნუ უპასუხებთ ამ წერილს." + +#: templates/templated_email/shared/_footer.email:5 +#: templates/templated_email/source/shared/footer.mjml:13 +#, python-format +msgctxt "Base email footer" +msgid "Sincerely, %(site_name)s" +msgstr "პატივისცემით, %(site_name)s" + +#: templates/templated_email/shared/_header.email:2 +#: templates/templated_email/source/account_delete.mjml:13 +#: templates/templated_email/source/confirm.mjml:13 +#: templates/templated_email/source/confirm_fulfillment.mjml:13 +#: templates/templated_email/source/confirm_order.mjml:14 +#: templates/templated_email/source/confirm_payment.mjml:13 +#: templates/templated_email/source/email_changed_notification.mjml:13 +#: templates/templated_email/source/export_failed.mjml:13 +#: templates/templated_email/source/export_products_file.mjml:13 +#: templates/templated_email/source/order_cancel.mjml:13 +#: templates/templated_email/source/order_refund.mjml:13 +#: templates/templated_email/source/password_reset.mjml:13 +#: templates/templated_email/source/request_email_change.mjml:13 +#: templates/templated_email/source/send_invoice.mjml:13 +#: templates/templated_email/source/set_customer_password.mjml:13 +#: templates/templated_email/source/set_password.mjml:13 +#: templates/templated_email/source/staff_confirm_order.mjml:14 +#: templates/templated_email/source/update_fulfillment.mjml:13 +msgctxt "Standard e-mail greeting" +msgid "Hi!" +msgstr "გამარჯობა!" + +#: templates/templated_email/source/account_delete.mjml:16 +#, python-format +msgctxt "Account delete e-mail text" +msgid "" +"You're receiving this e-mail because you or someone else has requested a " +"deletion of your user account at %(site_name)s.
Click the link below to" +" delete your account. Please note that this action is permanent and cannot " +"be reversed." +msgstr "" + +#: templates/templated_email/source/confirm.mjml:16 +#, python-format +msgctxt "Account confirmation e-mail text" +msgid "" +"In order to log into %(site_name)s, you have to confirm your email address " +"first. Please click the link below to do so and log into your account." +msgstr "" + +#: templates/templated_email/source/confirm_fulfillment.mjml:16 +msgctxt "Fulfillment confirmation email text" +msgid "Thank you for your order. Below is the list of fulfilled products." +msgstr "" + +#: templates/templated_email/source/confirm_fulfillment.mjml:21 +#: templates/templated_email/source/update_fulfillment.mjml:21 +#, python-format +msgctxt "Fulfillment confirmation email text" +msgid "" +"You can track your shipment with %(tracking_number)s link." +msgstr "" + +#: templates/templated_email/source/confirm_fulfillment.mjml:33 +msgctxt "Fulfillment digital products email text" +msgid "" +"You can download your digital products by clicking in download link(s)." +msgstr "" + +#: templates/templated_email/source/confirm_order.mjml:18 +#, python-format +msgctxt "Order confirmation e-mail text with payment details" +msgid "" +"Thank you for your order. Below is the list of ordered products. To see your" +" payment details please visit: %(order_details_url)s" +msgstr "" + +#: templates/templated_email/source/confirm_order.mjml:22 +msgctxt "Order confirmation e-mail text" +msgid "Thank you for your order. Below is the list of ordered products." +msgstr "" + +#: templates/templated_email/source/confirm_payment.mjml:16 +msgctxt "Payment confirmation e-mail text" +msgid "Thank you for your payment. Your payment was successfully processed." +msgstr "" + +#: templates/templated_email/source/email_changed_notification.mjml:16 +#, python-format +msgctxt "Email change e-mail text" +msgid "" +"You're receiving this e-mail because you or someone else has changed email " +"for your user account at %(site_name)s.
If you didn't request this " +"change, please contact the administrator." +msgstr "" + +#: templates/templated_email/source/export_failed.mjml:16 +msgctxt "Export products e-mail text" +msgid "" +"Sorry, we couldn't finish exporting products, some unexpected errors " +"occurred. Please try again." +msgstr "" + +#: templates/templated_email/source/export_products_file.mjml:16 +#, python-format +msgctxt "Export products e-mail text" +msgid "" +"Your file with products data is ready to download: %(csv_link)s" +msgstr "" +"თქვენი ფაილი პროდუქტების მონაცემებით მზად არის ჩამოსატვირთად: %(csv_link)s " + +#: templates/templated_email/source/order_cancel.mjml:16 +msgctxt "Order cancel e-mail text" +msgid "Your order has been canceled." +msgstr "თქვენი შეკვეთა გაუქმნდა." + +#: templates/templated_email/source/order_refund.mjml:16 +#, python-format +msgctxt "Order refund e-mail text" +msgid "A payment of %(amount)s %(currency)s has been refunded for your order." +msgstr "გადხდილი %(amount)s %(currency)s ანაზღაურდა თქვენი შეკვეთისთვის." + +#: templates/templated_email/source/partials/_fulfillment_lines.mjml:11 +#: templates/templated_email/source/partials/_fulfillment_lines.mjml:29 +#: templates/templated_email/source/partials/_order_lines.mjml:59 +msgctxt "Ordered item name" +msgid "Item" +msgstr "ნივთი" + +#: templates/templated_email/source/partials/_fulfillment_lines.mjml:12 +#: templates/templated_email/source/partials/_order_lines.mjml:60 +msgctxt "Quantity ordered of a product" +msgid "Quantity" +msgstr "რაოდენობა" + +#: templates/templated_email/source/partials/_fulfillment_lines.mjml:30 +msgctxt "Ordered item download links" +msgid "Download Link" +msgstr "გადმოწერის ბმული" + +#: templates/templated_email/source/partials/_order_lines.mjml:12 +msgctxt "E-mail order lines summary table" +msgid "Subtotal" +msgstr "ქვეტოტალი" + +#: templates/templated_email/source/partials/_order_lines.mjml:20 +msgctxt "E-mail order lines summary table" +msgid "Shipping" +msgstr "მიწოდება" + +#: templates/templated_email/source/partials/_order_lines.mjml:29 +msgctxt "E-mail order lines summary table" +msgid "Taxes (included)" +msgstr "დღგ (ჩათვლით)" + +#: templates/templated_email/source/partials/_order_lines.mjml:31 +msgctxt "E-mail order lines summary table" +msgid "Taxes" +msgstr "დღგ" + +#: templates/templated_email/source/partials/_order_lines.mjml:41 +msgctxt "E-mail order lines summary table" +msgid "Discount" +msgstr "ფასდაკლება" + +#: templates/templated_email/source/partials/_order_lines.mjml:50 +msgctxt "E-mail order lines summary table" +msgid "Total" +msgstr "ჯამი" + +#: templates/templated_email/source/partials/_order_lines.mjml:61 +msgctxt "Unit price of a product" +msgid "Per unit" +msgstr "ერთეულზე" + +#: templates/templated_email/source/partials/_order_lines.mjml:62 +msgctxt "Ordered item subtotal (unit price * quantity)" +msgid "Subtotal" +msgstr "ქვეტოტალი" + +#: templates/templated_email/source/password_reset.mjml:16 +#, python-format +msgctxt "Password reset e-mail text" +msgid "" +"You're receiving this e-mail because you or someone else has requested a " +"password for your user account at %(site_name)s.
It can be safely " +"ignored if you did not request a password reset. Click the link below to " +"reset your password." +msgstr "" + +#: templates/templated_email/source/request_email_change.mjml:16 +#, python-format +msgctxt "Email change e-mail text" +msgid "" +"You're receiving this e-mail because you or someone else has requested an " +"email change for your user account at %(site_name)s.
It can be safely " +"ignored if you did not request an email change. Click the link below to " +"confirm new email address." +msgstr "" + +#: templates/templated_email/source/send_invoice.mjml:16 +#, python-format +msgctxt "Send invoice e-mail text" +msgid "In order to download invoice %(number)s, click the link below." +msgstr "ინვოისის გადმოსაწერად %(number)s, დააჭირეთ ქვემოთ მოცემულ ბმულს." + +#: templates/templated_email/source/set_customer_password.mjml:16 +#, python-format +msgctxt "Set password for customer e-mail text" +msgid "" +"You're receiving this e-mail because you have to set password for your " +"customer account at %(site_name)s.
Click the link below to set up your " +"password." +msgstr "" + +#: templates/templated_email/source/set_password.mjml:16 +#, python-format +msgctxt "Set password for staff member e-mail text" +msgid "" +"You're receiving this e-mail because you have to set password for your staff" +" member account at %(site_name)s.
Click the link below to set up your " +"password." +msgstr "" + +#: templates/templated_email/source/staff_confirm_order.mjml:17 +#, python-format +msgctxt "Order confirmation staff e-mail text" +msgid "" +"Someone placed a new order in your store. To see order details please visit:" +" %(order_details_url)s" +msgstr "" + +#: templates/templated_email/source/update_fulfillment.mjml:16 +msgctxt "Fulfillment update email text" +msgid "" +"Your shipping status has been updated. Below is the list of ordered products" +" that have been updated with new tracking number." +msgstr "" diff --git a/locale/km/LC_MESSAGES/django.mo b/locale/km/LC_MESSAGES/django.mo index 94c506f60be..62c351e29ef 100644 Binary files a/locale/km/LC_MESSAGES/django.mo and b/locale/km/LC_MESSAGES/django.mo differ diff --git a/locale/ko/LC_MESSAGES/django.mo b/locale/ko/LC_MESSAGES/django.mo index 38546f972a1..0b43f5be085 100644 Binary files a/locale/ko/LC_MESSAGES/django.mo and b/locale/ko/LC_MESSAGES/django.mo differ diff --git a/locale/lt/LC_MESSAGES/django.mo b/locale/lt/LC_MESSAGES/django.mo index ef090b6844a..21c065c245e 100644 Binary files a/locale/lt/LC_MESSAGES/django.mo and b/locale/lt/LC_MESSAGES/django.mo differ diff --git a/locale/mn/LC_MESSAGES/django.mo b/locale/mn/LC_MESSAGES/django.mo index 54bf39e6577..5854d28c6c0 100644 Binary files a/locale/mn/LC_MESSAGES/django.mo and b/locale/mn/LC_MESSAGES/django.mo differ diff --git a/locale/my/LC_MESSAGES/django.mo b/locale/my/LC_MESSAGES/django.mo index a1e57f938b1..69766bc46fb 100644 Binary files a/locale/my/LC_MESSAGES/django.mo and b/locale/my/LC_MESSAGES/django.mo differ diff --git a/locale/nb/LC_MESSAGES/django.mo b/locale/nb/LC_MESSAGES/django.mo index 573c2ed249a..468d3cffac2 100644 Binary files a/locale/nb/LC_MESSAGES/django.mo and b/locale/nb/LC_MESSAGES/django.mo differ diff --git a/locale/nl/LC_MESSAGES/django.mo b/locale/nl/LC_MESSAGES/django.mo index cc7527ce327..30d12fadfeb 100644 Binary files a/locale/nl/LC_MESSAGES/django.mo and b/locale/nl/LC_MESSAGES/django.mo differ diff --git a/locale/pl/LC_MESSAGES/django.mo b/locale/pl/LC_MESSAGES/django.mo index c44f3537805..02de034841e 100644 Binary files a/locale/pl/LC_MESSAGES/django.mo and b/locale/pl/LC_MESSAGES/django.mo differ diff --git a/locale/pt/LC_MESSAGES/django.mo b/locale/pt/LC_MESSAGES/django.mo index 4f7ab4dc561..e913290ec5e 100644 Binary files a/locale/pt/LC_MESSAGES/django.mo and b/locale/pt/LC_MESSAGES/django.mo differ diff --git a/locale/pt_BR/LC_MESSAGES/django.mo b/locale/pt_BR/LC_MESSAGES/django.mo index 92f5f8b4566..a6abbb02ddf 100644 Binary files a/locale/pt_BR/LC_MESSAGES/django.mo and b/locale/pt_BR/LC_MESSAGES/django.mo differ diff --git a/locale/ro/LC_MESSAGES/django.mo b/locale/ro/LC_MESSAGES/django.mo index 88d5dde5e29..1385322e666 100644 Binary files a/locale/ro/LC_MESSAGES/django.mo and b/locale/ro/LC_MESSAGES/django.mo differ diff --git a/locale/ru/LC_MESSAGES/django.mo b/locale/ru/LC_MESSAGES/django.mo index 03b93f2880e..09d31a81fd0 100644 Binary files a/locale/ru/LC_MESSAGES/django.mo and b/locale/ru/LC_MESSAGES/django.mo differ diff --git a/locale/si/LC_MESSAGES/django.mo b/locale/si/LC_MESSAGES/django.mo index 9394af03112..9e2d7d5a52d 100644 Binary files a/locale/si/LC_MESSAGES/django.mo and b/locale/si/LC_MESSAGES/django.mo differ diff --git a/locale/sk/LC_MESSAGES/django.mo b/locale/sk/LC_MESSAGES/django.mo index c9a90ce6d02..940cc2fc34d 100644 Binary files a/locale/sk/LC_MESSAGES/django.mo and b/locale/sk/LC_MESSAGES/django.mo differ diff --git a/locale/sl/LC_MESSAGES/django.mo b/locale/sl/LC_MESSAGES/django.mo index cfbef6e9ca2..b6558cf0f39 100644 Binary files a/locale/sl/LC_MESSAGES/django.mo and b/locale/sl/LC_MESSAGES/django.mo differ diff --git a/locale/sq/LC_MESSAGES/django.mo b/locale/sq/LC_MESSAGES/django.mo index e49d13d691a..20559332b4d 100644 Binary files a/locale/sq/LC_MESSAGES/django.mo and b/locale/sq/LC_MESSAGES/django.mo differ diff --git a/locale/sr/LC_MESSAGES/django.mo b/locale/sr/LC_MESSAGES/django.mo index f363728e120..efe2ddbb54a 100644 Binary files a/locale/sr/LC_MESSAGES/django.mo and b/locale/sr/LC_MESSAGES/django.mo differ diff --git a/locale/sv/LC_MESSAGES/django.mo b/locale/sv/LC_MESSAGES/django.mo index c74cbe5f966..98065972f8e 100644 Binary files a/locale/sv/LC_MESSAGES/django.mo and b/locale/sv/LC_MESSAGES/django.mo differ diff --git a/locale/sw/LC_MESSAGES/django.mo b/locale/sw/LC_MESSAGES/django.mo index 43ab7cfda03..cbe09dbe9db 100644 Binary files a/locale/sw/LC_MESSAGES/django.mo and b/locale/sw/LC_MESSAGES/django.mo differ diff --git a/locale/ta/LC_MESSAGES/django.mo b/locale/ta/LC_MESSAGES/django.mo index 5037bc4c692..52c11a08003 100644 Binary files a/locale/ta/LC_MESSAGES/django.mo and b/locale/ta/LC_MESSAGES/django.mo differ diff --git a/locale/th/LC_MESSAGES/django.mo b/locale/th/LC_MESSAGES/django.mo index 685bbafa833..acb48583049 100644 Binary files a/locale/th/LC_MESSAGES/django.mo and b/locale/th/LC_MESSAGES/django.mo differ diff --git a/locale/tr/LC_MESSAGES/django.mo b/locale/tr/LC_MESSAGES/django.mo index 056128a8749..a9d65421259 100644 Binary files a/locale/tr/LC_MESSAGES/django.mo and b/locale/tr/LC_MESSAGES/django.mo differ diff --git a/locale/uk/LC_MESSAGES/django.mo b/locale/uk/LC_MESSAGES/django.mo index 4780b92ba0b..2538410d6f0 100644 Binary files a/locale/uk/LC_MESSAGES/django.mo and b/locale/uk/LC_MESSAGES/django.mo differ diff --git a/locale/vi/LC_MESSAGES/django.mo b/locale/vi/LC_MESSAGES/django.mo index f7cc1d66af6..770077675ef 100644 Binary files a/locale/vi/LC_MESSAGES/django.mo and b/locale/vi/LC_MESSAGES/django.mo differ diff --git a/locale/zh_Hans/LC_MESSAGES/django.mo b/locale/zh_Hans/LC_MESSAGES/django.mo index 53716acb375..0606183f58c 100644 Binary files a/locale/zh_Hans/LC_MESSAGES/django.mo and b/locale/zh_Hans/LC_MESSAGES/django.mo differ diff --git a/locale/zh_Hant/LC_MESSAGES/django.mo b/locale/zh_Hant/LC_MESSAGES/django.mo index fbd34570a6b..0305ca0fb68 100644 Binary files a/locale/zh_Hant/LC_MESSAGES/django.mo and b/locale/zh_Hant/LC_MESSAGES/django.mo differ diff --git a/poetry.lock b/poetry.lock index a78f0d6bf18..3dfc99b7e59 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,64 +1,64 @@ [[package]] -category = "main" -description = "Adyen Python Api" name = "adyen" +version = "3.0.0" +description = "Adyen Python Api" +category = "main" optional = false python-versions = "*" -version = "3.0.0" [[package]] -category = "main" -description = "Low-level AMQP client for Python (fork of amqplib)." name = "amqp" +version = "5.0.1" +description = "Low-level AMQP client for Python (fork of amqplib)." +category = "main" optional = false python-versions = ">=3.6" -version = "5.0.1" [package.dependencies] vine = "5.0.0" [[package]] -category = "main" -description = "A library for parsing ISO 8601 strings." name = "aniso8601" +version = "7.0.0" +description = "A library for parsing ISO 8601 strings." +category = "main" optional = false python-versions = "*" -version = "7.0.0" [[package]] -category = "dev" -description = "apipkg: namespace control and lazy-import mechanism" name = "apipkg" +version = "1.5" +description = "apipkg: namespace control and lazy-import mechanism" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.5" [[package]] -category = "dev" -description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." name = "appdirs" +version = "1.4.4" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" optional = false python-versions = "*" -version = "1.4.4" [[package]] -category = "main" -description = "ASGI specs, helper code, and adapters" name = "asgiref" +version = "3.2.10" +description = "ASGI specs, helper code, and adapters" +category = "main" optional = false python-versions = ">=3.5" -version = "3.2.10" [package.extras] tests = ["pytest", "pytest-asyncio"] [[package]] -category = "dev" -description = "An abstract syntax tree for Python with inference support." name = "astroid" +version = "2.4.2" +description = "An abstract syntax tree for Python with inference support." +category = "dev" optional = false python-versions = ">=3.5" -version = "2.4.2" [package.dependencies] lazy-object-proxy = ">=1.4.0,<1.5.0" @@ -66,45 +66,45 @@ six = ">=1.12,<2.0" wrapt = ">=1.11,<2.0" [[package]] -category = "dev" -description = "Atomic file writes." -marker = "sys_platform == \"win32\"" name = "atomicwrites" +version = "1.4.0" +description = "Atomic file writes." +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.4.0" [[package]] -category = "dev" -description = "Classes Without Boilerplate" name = "attrs" +version = "20.2.0" +description = "Classes Without Boilerplate" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "20.1.0" [package.extras] -dev = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "sphinx-rtd-theme", "pre-commit"] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "sphinx-rtd-theme", "pre-commit"] docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] -tests = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] [[package]] -category = "main" -description = "Internationalization utilities" name = "babel" +version = "2.8.0" +description = "Internationalization utilities" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.8.0" [package.dependencies] pytz = ">=2015.7" [[package]] -category = "main" -description = "Screen-scraping library" name = "beautifulsoup4" +version = "4.7.1" +description = "Screen-scraping library" +category = "main" optional = false python-versions = "*" -version = "4.7.1" [package.dependencies] soupsieve = ">=1.2" @@ -114,28 +114,28 @@ html5lib = ["html5lib"] lxml = ["lxml"] [[package]] -category = "dev" -description = "Print ASCII tables for terminals" name = "beautifultable" +version = "0.7.0" +description = "Print ASCII tables for terminals" +category = "dev" optional = false python-versions = "*" -version = "0.7.0" [[package]] -category = "main" -description = "Python multiprocessing fork with improvements and bugfixes" name = "billiard" +version = "3.6.3.0" +description = "Python multiprocessing fork with improvements and bugfixes" +category = "main" optional = false python-versions = "*" -version = "3.6.3.0" [[package]] -category = "dev" -description = "The uncompromising code formatter." name = "black" +version = "19.10b0" +description = "The uncompromising code formatter." +category = "dev" optional = false python-versions = ">=3.6" -version = "19.10b0" [package.dependencies] appdirs = "*" @@ -150,64 +150,60 @@ typed-ast = ">=1.4.0" d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] [[package]] -category = "main" -description = "The AWS SDK for Python" name = "boto3" +version = "1.16.7" +description = "The AWS SDK for Python" +category = "main" optional = false python-versions = "*" -version = "1.15.11" [package.dependencies] -botocore = ">=1.18.11,<1.19.0" +botocore = ">=1.19.7,<1.20.0" jmespath = ">=0.7.1,<1.0.0" s3transfer = ">=0.3.0,<0.4.0" [[package]] -category = "main" -description = "Low-level, data-driven core of boto 3." name = "botocore" +version = "1.19.7" +description = "Low-level, data-driven core of boto 3." +category = "main" optional = false python-versions = "*" -version = "1.18.11" [package.dependencies] jmespath = ">=0.7.1,<1.0.0" python-dateutil = ">=2.1,<3.0.0" - -[package.dependencies.urllib3] -python = "<3.4.0 || >=3.5.0" -version = ">=1.20,<1.26" +urllib3 = {version = ">=1.25.4,<1.26", markers = "python_version != \"3.4\""} [[package]] -category = "main" -description = "Braintree Python Library" name = "braintree" +version = "4.4.0" +description = "Braintree Python Library" +category = "main" optional = false python-versions = "*" -version = "4.4.0" [package.dependencies] requests = ">=0.11.1,<3.0" [[package]] -category = "main" -description = "Extensible memoizing collections and decorators" name = "cachetools" +version = "4.1.1" +description = "Extensible memoizing collections and decorators" +category = "main" optional = false python-versions = "~=3.5" -version = "4.1.1" [[package]] -category = "main" -description = "cffi-based cairo bindings for Python" name = "cairocffi" +version = "1.1.0" +description = "cffi-based cairo bindings for Python" +category = "main" optional = false python-versions = ">= 3.5" -version = "1.1.0" [package.dependencies] cffi = ">=1.1.0" -setuptools = ">=39.2.0" [package.extras] doc = ["sphinx", "sphinx-rtd-theme"] @@ -215,12 +211,12 @@ test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"] xcb = ["xcffib (>=0.3.2)"] [[package]] -category = "main" -description = "A Simple SVG Converter based on Cairo" name = "cairosvg" +version = "2.4.2" +description = "A Simple SVG Converter based on Cairo" +category = "main" optional = false python-versions = ">= 3.5" -version = "2.4.2" [package.dependencies] cairocffi = "*" @@ -234,12 +230,12 @@ doc = ["sphinx", "sphinx-rtd-theme"] test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"] [[package]] -category = "main" -description = "Distributed Task Queue." name = "celery" +version = "5.0.1" +description = "Distributed Task Queue." +category = "main" optional = false python-versions = ">=3.6," -version = "5.0.0" [package.dependencies] billiard = ">=3.6.3.0,<4.0" @@ -248,20 +244,17 @@ click-didyoumean = ">=0.0.3" click-repl = ">=0.1.6" kombu = ">=5.0.0,<6.0" pytz = ">0.0-dev" +redis = {version = ">=3.2.0", optional = true, markers = "extra == \"redis\""} vine = ">=5.0.0,<6.0" -[package.dependencies.redis] -optional = true -version = ">=3.2.0" - [package.extras] arangodb = ["pyArango (>=1.3.2)"] auth = ["cryptography"] -azureblockblob = ["azure-storage (0.36.0)", "azure-common (1.1.5)", "azure-storage-common (1.1.0)"] +azureblockblob = ["azure-storage (==0.36.0)", "azure-common (==1.1.5)", "azure-storage-common (==1.1.0)"] brotli = ["brotli (>=1.0.0)", "brotlipy (>=0.7.0)"] cassandra = ["cassandra-driver (<3.21.0)"] consul = ["python-consul"] -cosmosdbsql = ["pydocumentdb (2.3.2)"] +cosmosdbsql = ["pydocumentdb (==2.3.2)"] couchbase = ["couchbase (>=3.0.0)"] couchdb = ["pycouchdb"] django = ["Django (>=1.11)"] @@ -272,7 +265,7 @@ gevent = ["gevent (>=1.0.0)"] librabbitmq = ["librabbitmq (>=1.5.0)"] lzma = ["backports.lzma"] memcache = ["pylibmc"] -mongodb = ["pymongo (>=3.3.0)"] +mongodb = ["pymongo[srv] (>=3.3.0)"] msgpack = ["msgpack"] pymemcache = ["python-memcached"] pyro = ["pyro4"] @@ -281,73 +274,73 @@ s3 = ["boto3 (>=1.9.125)"] slmq = ["softlayer-messaging (>=1.0.3)"] solar = ["ephem"] sqlalchemy = ["sqlalchemy"] -sqs = ["boto3 (>=1.9.125)", "pycurl (7.43.0.5)"] +sqs = ["boto3 (>=1.9.125)", "pycurl (==7.43.0.5)"] tblib = ["tblib (>=1.3.0)", "tblib (>=1.5.0)"] yaml = ["PyYAML (>=3.10)"] zookeeper = ["kazoo (>=1.3.1)"] zstd = ["zstandard"] [[package]] -category = "main" -description = "Python package for providing Mozilla's CA Bundle." name = "certifi" +version = "2020.6.20" +description = "Python package for providing Mozilla's CA Bundle." +category = "main" optional = false python-versions = "*" -version = "2020.6.20" [[package]] -category = "main" -description = "Foreign Function Interface for Python calling C code." name = "cffi" +version = "1.14.3" +description = "Foreign Function Interface for Python calling C code." +category = "main" optional = false python-versions = "*" -version = "1.14.2" [package.dependencies] pycparser = "*" [[package]] -category = "dev" -description = "Validate configuration and produce human readable error messages." name = "cfgv" +version = "3.2.0" +description = "Validate configuration and produce human readable error messages." +category = "dev" optional = false python-versions = ">=3.6.1" -version = "3.2.0" [[package]] -category = "main" -description = "Universal encoding detector for Python 2 and 3" name = "chardet" +version = "3.0.4" +description = "Universal encoding detector for Python 2 and 3" +category = "main" optional = false python-versions = "*" -version = "3.0.4" [[package]] -category = "main" -description = "Composable command line interface toolkit" name = "click" +version = "7.1.2" +description = "Composable command line interface toolkit" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "7.1.2" [[package]] -category = "main" -description = "Enable git-like did-you-mean feature in click." name = "click-didyoumean" +version = "0.0.3" +description = "Enable git-like did-you-mean feature in click." +category = "main" optional = false python-versions = "*" -version = "0.0.3" [package.dependencies] click = "*" [[package]] -category = "main" -description = "REPL plugin for Click" name = "click-repl" +version = "0.1.6" +description = "REPL plugin for Click" +category = "main" optional = false python-versions = "*" -version = "0.1.6" [package.dependencies] click = "*" @@ -355,46 +348,45 @@ prompt-toolkit = "*" six = "*" [[package]] -category = "dev" -description = "Hosted coverage reports for GitHub, Bitbucket and Gitlab" name = "codecov" +version = "2.1.10" +description = "Hosted coverage reports for GitHub, Bitbucket and Gitlab" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.1.9" [package.dependencies] coverage = "*" requests = ">=2.7.9" [[package]] -category = "dev" -description = "Cross-platform colored terminal text." name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "0.4.3" [[package]] -category = "dev" -description = "Code coverage measurement for Python" name = "coverage" +version = "5.3" +description = "Code coverage measurement for Python" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" -version = "5.3" [package.extras] toml = ["toml"] [[package]] -category = "main" -description = "CSS selectors for Python ElementTree" name = "cssselect2" +version = "0.3.0" +description = "CSS selectors for Python ElementTree" +category = "main" optional = false python-versions = ">=3.5" -version = "0.3.0" [package.dependencies] -setuptools = ">=39.2.0" tinycss2 = "*" webencodings = "*" @@ -403,44 +395,44 @@ doc = ["sphinx", "sphinx-rtd-theme"] test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"] [[package]] -category = "main" -description = "XML bomb protection for Python stdlib modules" name = "defusedxml" +version = "0.6.0" +description = "XML bomb protection for Python stdlib modules" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "0.6.0" [[package]] -category = "dev" -description = "Distribution utilities" name = "distlib" +version = "0.3.1" +description = "Distribution utilities" +category = "dev" optional = false python-versions = "*" -version = "0.3.1" [[package]] -category = "main" -description = "Use Database URLs in your Django Application." name = "dj-database-url" +version = "0.5.0" +description = "Use Database URLs in your Django Application." +category = "main" optional = false python-versions = "*" -version = "0.5.0" [[package]] -category = "main" -description = "Use an URL to configure email backend settings in your Django Application." name = "dj-email-url" +version = "1.0.1" +description = "Use an URL to configure email backend settings in your Django Application." +category = "main" optional = false python-versions = "*" -version = "1.0.1" [[package]] -category = "main" -description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design." name = "django" +version = "3.1.2" +description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design." +category = "main" optional = false python-versions = ">=3.6" -version = "3.1.2" [package.dependencies] asgiref = ">=3.2.10,<3.3.0" @@ -452,31 +444,31 @@ argon2 = ["argon2-cffi (>=16.1.0)"] bcrypt = ["bcrypt"] [[package]] -category = "main" -description = "A helper class for handling configuration defaults of packaged apps gracefully." name = "django-appconf" +version = "1.0.4" +description = "A helper class for handling configuration defaults of packaged apps gracefully." +category = "main" optional = false python-versions = "*" -version = "1.0.4" [package.dependencies] django = "*" [[package]] -category = "main" -description = "Use Cache URLs in your Django application." name = "django-cache-url" +version = "3.1.2" +description = "Use Cache URLs in your Django application." +category = "main" optional = false python-versions = "*" -version = "3.1.2" [[package]] -category = "main" -description = "Provides a country field for Django models." name = "django-countries" +version = "6.1.3" +description = "Provides a country field for Django models." +category = "main" optional = false python-versions = "*" -version = "6.1.3" [package.extras] dev = ["tox", "black", "django", "pytest", "pytest-django", "djangorestframework", "graphene-django"] @@ -484,54 +476,54 @@ maintainer = ["transifex-client", "zest.releaser", "django"] test = ["pytest", "pytest-django", "pytest-cov", "graphene-django"] [[package]] -category = "dev" -description = "A configurable set of panels that display various debug information about the current request/response." name = "django-debug-toolbar" +version = "3.1.1" +description = "A configurable set of panels that display various debug information about the current request/response." +category = "dev" optional = false python-versions = ">=3.5" -version = "3.1.1" [package.dependencies] Django = ">=2.2" sqlparse = ">=0.2.0" [[package]] -category = "dev" -description = "Request History Panel for Django Debug Toolbar" name = "django-debug-toolbar-request-history" +version = "0.1.3" +description = "Request History Panel for Django Debug Toolbar" +category = "dev" optional = false python-versions = "*" -version = "0.1.3" [package.dependencies] django-debug-toolbar = ">=2.0" [[package]] -category = "dev" -description = "Extensions for Django" name = "django-extensions" +version = "3.0.9" +description = "Extensions for Django" +category = "dev" optional = false python-versions = ">=3.5" -version = "3.0.9" [[package]] -category = "main" -description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically." name = "django-filter" +version = "2.4.0" +description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically." +category = "main" optional = false python-versions = ">=3.5" -version = "2.4.0" [package.dependencies] Django = ">=2.2" [[package]] -category = "dev" -description = "Django Debug Toolbar for GraphiQL IDE" name = "django-graphiql-debug-toolbar" +version = "0.1.4" +description = "Django Debug Toolbar for GraphiQL IDE" +category = "dev" optional = false python-versions = "*" -version = "0.1.4" [package.dependencies] Django = ">=2.0" @@ -539,20 +531,20 @@ django-debug-toolbar = ">=2.0" graphene-django = ">=2.0.0" [[package]] -category = "main" -description = "script tag with additional attributes for django.forms.Media" name = "django-js-asset" +version = "1.2.2" +description = "script tag with additional attributes for django.forms.Media" +category = "main" optional = false python-versions = "*" -version = "1.2.2" [[package]] -category = "main" -description = "Convenient fields and classes for handling measurements" name = "django-measurement" +version = "3.2.3" +description = "Convenient fields and classes for handling measurements" +category = "main" optional = false python-versions = "*" -version = "3.2.3" [package.dependencies] django = ">=2.2" @@ -560,24 +552,24 @@ django-appconf = ">=1.0.2" measurement = ">=1.6,<4.0" [[package]] -category = "main" -description = "Utilities for implementing Modified Preorder Tree Traversal with your Django Models and working with trees of Model instances." name = "django-mptt" +version = "0.11.0" +description = "Utilities for implementing Modified Preorder Tree Traversal with your Django Models and working with trees of Model instances." +category = "main" optional = false python-versions = ">=3.5" -version = "0.11.0" [package.dependencies] Django = ">=1.11" django-js-asset = "*" [[package]] -category = "main" -description = "An international phone number field for django models." name = "django-phonenumber-field" +version = "5.0.0" +description = "An international phone number field for django models." +category = "main" optional = false python-versions = ">=3.5" -version = "5.0.0" [package.dependencies] Django = ">=2.2" @@ -587,12 +579,12 @@ phonenumbers = ["phonenumbers (>=7.0.2)"] phonenumberslite = ["phonenumberslite (>=7.0.2)"] [[package]] -category = "main" -description = "Django fields for the prices module" name = "django-prices" +version = "2.2.0" +description = "Django fields for the prices module" +category = "main" optional = false python-versions = "*" -version = "2.2.0" [package.dependencies] Babel = ">=2.2" @@ -601,12 +593,12 @@ enmerkar = ">=0.7.1" prices = ">=1.0.0" [[package]] -category = "main" -description = "openexchangerates.org support for django-prices" name = "django-prices-openexchangerates" +version = "1.1.0" +description = "openexchangerates.org support for django-prices" +category = "main" optional = false python-versions = "*" -version = "1.1.0" [package.dependencies] Django = ">=1.11" @@ -614,12 +606,12 @@ django-prices = ">=1.0.0" prices = ">=1.0.0" [[package]] -category = "main" -description = "vatlayer.com support for django" name = "django-prices-vatlayer" +version = "1.1.0" +description = "vatlayer.com support for django" +category = "main" optional = false python-versions = "*" -version = "1.1.0" [package.dependencies] Django = ">=1.11" @@ -628,42 +620,39 @@ prices = ">=1.0.0" requests = "*" [[package]] -category = "main" -description = "Full featured redis cache backend for Django." name = "django-redis" +version = "4.12.1" +description = "Full featured redis cache backend for Django." +category = "main" optional = false python-versions = ">=3.5" -version = "4.12.1" [package.dependencies] Django = ">=2.2" redis = ">=3.0.0" [[package]] -category = "main" -description = "Render a particular block from a template to a string." name = "django-render-block" +version = "0.8.1" +description = "Render a particular block from a template to a string." +category = "main" optional = false python-versions = ">=3.5" -version = "0.7" [package.dependencies] django = ">=2.2" [[package]] -category = "main" -description = "Support for many storage backends in Django" name = "django-storages" +version = "1.10.1" +description = "Support for many storage backends in Django" +category = "main" optional = false python-versions = ">=3.5" -version = "1.10.1" [package.dependencies] Django = ">=2.2" - -[package.dependencies.google-cloud-storage] -optional = true -version = ">=1.15.0" +google-cloud-storage = {version = ">=1.15.0", optional = true, markers = "extra == \"google\""} [package.extras] azure = ["azure-storage-blob (>=1.3.1,<12.0.0)"] @@ -674,12 +663,12 @@ libcloud = ["apache-libcloud"] sftp = ["paramiko"] [[package]] -category = "dev" -description = "Mypy stubs for Django" name = "django-stubs" +version = "1.2.0" +description = "Mypy stubs for Django" +category = "dev" optional = false python-versions = ">=3.6" -version = "1.2.0" [package.dependencies] django = "*" @@ -687,36 +676,36 @@ mypy = ">=0.730" typing-extensions = "*" [[package]] -category = "main" -description = "A Django oriented templated / transaction email abstraction" name = "django-templated-email" +version = "2.3.0" +description = "A Django oriented templated / transaction email abstraction" +category = "main" optional = false python-versions = "*" -version = "2.3.0" [package.dependencies] django-render-block = ">=0.5" six = ">=1" [[package]] -category = "main" -description = "A drop-in replacement for django's ImageField that provides a flexible, intuitive and easily-extensible interface for creating new images from the one assigned to the field." name = "django-versatileimagefield" +version = "2.0" +description = "A drop-in replacement for django's ImageField that provides a flexible, intuitive and easily-extensible interface for creating new images from the one assigned to the field." +category = "main" optional = false python-versions = "*" -version = "2.0" [package.dependencies] Pillow = ">=2.4.0" python-magic = ">=0.4.15,<1.0.0" [[package]] -category = "main" -description = "Convert basic HTML into DraftJS JSON format." name = "draftjs-sanitizer" +version = "1.0.0" +description = "Convert basic HTML into DraftJS JSON format." +category = "main" optional = false python-versions = "*" -version = "1.0.0" [package.dependencies] urllib3 = "*" @@ -725,32 +714,32 @@ urllib3 = "*" dev = ["pre-commit", "pytest", "mock"] [[package]] -category = "main" -description = "Utilities for using Babel in Django" name = "enmerkar" +version = "0.7.1" +description = "Utilities for using Babel in Django" +category = "main" optional = false python-versions = "*" -version = "0.7.1" [package.dependencies] babel = ">=1.3" django = ">=2.2" [[package]] -category = "main" -description = "An implementation of lxml.xmlfile for the standard library" name = "et-xmlfile" +version = "1.0.1" +description = "An implementation of lxml.xmlfile for the standard library" +category = "main" optional = false python-versions = "*" -version = "1.0.1" [[package]] -category = "dev" -description = "execnet: rapid multi-Python deployment" name = "execnet" +version = "1.7.1" +description = "execnet: rapid multi-Python deployment" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.7.1" [package.dependencies] apipkg = ">=1.4" @@ -759,32 +748,32 @@ apipkg = ">=1.4" testing = ["pre-commit"] [[package]] -category = "main" -description = "Faker is a Python package that generates fake data for you." name = "faker" +version = "4.14.0" +description = "Faker is a Python package that generates fake data for you." +category = "main" optional = false python-versions = ">=3.5" -version = "4.1.3" [package.dependencies] python-dateutil = ">=2.4" text-unidecode = "1.3" [[package]] -category = "dev" -description = "A platform independent file lock." name = "filelock" +version = "3.0.12" +description = "A platform independent file lock." +category = "dev" optional = false python-versions = "*" -version = "3.0.12" [[package]] -category = "dev" -description = "the modular source code checker: pep8 pyflakes and co" name = "flake8" +version = "3.8.4" +description = "the modular source code checker: pep8 pyflakes and co" +category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -version = "3.8.4" [package.dependencies] mccabe = ">=0.6.0,<0.7.0" @@ -792,59 +781,55 @@ pycodestyle = ">=2.6.0a1,<2.7.0" pyflakes = ">=2.2.0,<2.3.0" [[package]] -category = "main" -description = "Let your Python tests travel through time" name = "freezegun" +version = "0.3.15" +description = "Let your Python tests travel through time" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "0.3.15" [package.dependencies] python-dateutil = ">=1.0,<2.0 || >2.0" six = "*" [[package]] -category = "dev" -description = "Git Object Database" name = "gitdb" +version = "4.0.5" +description = "Git Object Database" +category = "dev" optional = false python-versions = ">=3.4" -version = "4.0.5" [package.dependencies] smmap = ">=3.0.1,<4" [[package]] -category = "dev" -description = "Python Git Library" name = "gitpython" +version = "3.1.11" +description = "Python Git Library" +category = "dev" optional = false python-versions = ">=3.4" -version = "3.1.7" [package.dependencies] gitdb = ">=4.0.1,<5" [[package]] -category = "main" -description = "Google API client core library" name = "google-api-core" +version = "1.23.0" +description = "Google API client core library" +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -version = "1.22.2" [package.dependencies] google-auth = ">=1.21.1,<2.0dev" googleapis-common-protos = ">=1.6.0,<2.0dev" +grpcio = {version = ">=1.29.0,<2.0dev", optional = true, markers = "extra == \"grpc\""} protobuf = ">=3.12.0" pytz = "*" requests = ">=2.18.0,<3.0.0dev" -setuptools = ">=34.0.0" -six = ">=1.10.0" - -[package.dependencies.grpcio] -optional = true -version = ">=1.29.0,<2.0dev" +six = ">=1.13.0" [package.extras] grpc = ["grpcio (>=1.29.0,<2.0dev)"] @@ -852,30 +837,29 @@ grpcgcp = ["grpcio-gcp (>=0.2.2)"] grpcio-gcp = ["grpcio-gcp (>=0.2.2)"] [[package]] -category = "main" -description = "Google Authentication Library" name = "google-auth" +version = "1.22.1" +description = "Google Authentication Library" +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -version = "1.21.3" [package.dependencies] cachetools = ">=2.0.0,<5.0" pyasn1-modules = ">=0.2.1" -setuptools = ">=40.3.0" +rsa = {version = ">=3.1.4,<5", markers = "python_version >= \"3.5\""} six = ">=1.9.0" -[package.dependencies.rsa] -python = ">=3.5" -version = ">=3.1.4,<5" +[package.extras] +aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)"] [[package]] -category = "main" -description = "Google Cloud API client core library" name = "google-cloud-core" +version = "1.4.3" +description = "Google Cloud API client core library" +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -version = "1.4.1" [package.dependencies] google-api-core = ">=1.19.0,<2.0.0dev" @@ -884,29 +868,26 @@ google-api-core = ">=1.19.0,<2.0.0dev" grpc = ["grpcio (>=1.8.2,<2.0dev)"] [[package]] -category = "main" -description = "Google Cloud Pub/Sub API client library" name = "google-cloud-pubsub" +version = "2.1.0" +description = "Google Cloud Pub/Sub API client library" +category = "main" optional = false python-versions = ">=3.6" -version = "2.1.0" [package.dependencies] +google-api-core = {version = ">=1.22.2,<2.0.0dev", extras = ["grpc"]} grpc-google-iam-v1 = ">=0.12.3,<0.13dev" libcst = ">=0.3.10" proto-plus = ">=1.7.1" -[package.dependencies.google-api-core] -extras = ["grpc"] -version = ">=1.22.2,<2.0.0dev" - [[package]] -category = "main" -description = "Google Cloud Storage API client library" name = "google-cloud-storage" +version = "1.32.0" +description = "Google Cloud Storage API client library" +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -version = "1.31.2" [package.dependencies] google-auth = ">=1.11.0,<2.0dev" @@ -915,13 +896,12 @@ google-resumable-media = ">=1.0.0,<2.0dev" requests = ">=2.18.0,<3.0.0dev" [[package]] -category = "main" -description = "A python wrapper of the C library 'Google CRC32C'" -marker = "python_version >= \"3.5\"" name = "google-crc32c" +version = "1.0.0" +description = "A python wrapper of the C library 'Google CRC32C'" +category = "main" optional = false python-versions = ">=3.5" -version = "1.0.0" [package.dependencies] cffi = ">=1.0.0" @@ -930,67 +910,66 @@ cffi = ">=1.0.0" testing = ["pytest"] [[package]] -category = "main" -description = "Address validation helpers for Google's i18n address database" name = "google-i18n-address" +version = "2.4.0" +description = "Address validation helpers for Google's i18n address database" +category = "main" optional = false python-versions = "*" -version = "2.4.0" [package.dependencies] requests = ">=2.7.0" [[package]] -category = "main" -description = "A Python implementation of Google Analytics Measurement Protocol" name = "google-measurement-protocol" +version = "1.1.0" +description = "A Python implementation of Google Analytics Measurement Protocol" +category = "main" optional = false python-versions = "*" -version = "1.1.0" [package.dependencies] prices = ">=1.0.0" requests = ">=2.0,<3.0a0" [[package]] -category = "main" -description = "Utilities for Google Media Downloads and Resumable Uploads" name = "google-resumable-media" +version = "1.1.0" +description = "Utilities for Google Media Downloads and Resumable Uploads" +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" -version = "1.0.0" [package.dependencies] +google-crc32c = {version = ">=1.0,<2.0dev", markers = "python_version >= \"3.5\""} six = "*" -[package.dependencies.google-crc32c] -python = ">=3.5" -version = ">=1.0,<2.0dev" - [package.extras] +aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)"] requests = ["requests (>=2.18.0,<3.0.0dev)"] [[package]] -category = "main" -description = "Common protobufs used in Google APIs" name = "googleapis-common-protos" +version = "1.52.0" +description = "Common protobufs used in Google APIs" +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -version = "1.52.0" [package.dependencies] +grpcio = {version = ">=1.0.0", optional = true, markers = "extra == \"grpc\""} protobuf = ">=3.6.0" [package.extras] grpc = ["grpcio (>=1.0.0)"] [[package]] -category = "main" -description = "GraphQL Framework for Python" name = "graphene" +version = "2.1.8" +description = "GraphQL Framework for Python" +category = "main" optional = false python-versions = "*" -version = "2.1.8" [package.dependencies] aniso8601 = ">=3,<=7" @@ -1004,12 +983,12 @@ sqlalchemy = ["graphene-sqlalchemy"] test = ["pytest", "pytest-benchmark", "pytest-cov", "pytest-mock", "snapshottest", "coveralls", "promise", "six", "mock", "pytz", "iso8601"] [[package]] -category = "main" -description = "Graphene Django integration" name = "graphene-django" +version = "2.13.0" +description = "Graphene Django integration" +category = "main" optional = false python-versions = "*" -version = "2.13.0" [package.dependencies] Django = ">=1.11" @@ -1021,28 +1000,28 @@ six = ">=1.10.0" unidecode = ">=1.1.1,<2" [package.extras] -dev = ["black (19.10b0)", "flake8 (3.7.9)", "flake8-black (0.1.1)", "flake8-bugbear (20.1.4)", "pytest (>=3.6.3)", "pytest-cov", "coveralls", "mock", "pytz", "pytest-django (>=3.3.2)", "djangorestframework (>=3.6.3)", "django-filter (<2)", "django-filter (>=2)"] +dev = ["black (==19.10b0)", "flake8 (==3.7.9)", "flake8-black (==0.1.1)", "flake8-bugbear (==20.1.4)", "pytest (>=3.6.3)", "pytest-cov", "coveralls", "mock", "pytz", "pytest-django (>=3.3.2)", "djangorestframework (>=3.6.3)", "django-filter (<2)", "django-filter (>=2)"] rest_framework = ["djangorestframework (>=3.6.3)"] test = ["pytest (>=3.6.3)", "pytest-cov", "coveralls", "mock", "pytz", "pytest-django (>=3.3.2)", "djangorestframework (>=3.6.3)", "django-filter (<2)", "django-filter (>=2)"] [[package]] -category = "main" -description = "Federation implementation for graphene" name = "graphene-federation" +version = "0.1.0" +description = "Federation implementation for graphene" +category = "main" optional = false python-versions = "*" -version = "0.1.0" [package.dependencies] graphene = ">=2.1.0,<3" [[package]] -category = "main" -description = "GraphQL implementation for Python" name = "graphql-core" +version = "2.3.2" +description = "GraphQL implementation for Python" +category = "main" optional = false python-versions = "*" -version = "2.3.2" [package.dependencies] promise = ">=2.3,<3" @@ -1051,15 +1030,15 @@ six = ">=1.10.0" [package.extras] gevent = ["gevent (>=1.1)"] -test = ["six (1.14.0)", "pyannotate (1.2.0)", "pytest (4.6.10)", "pytest-django (3.9.0)", "pytest-cov (2.8.1)", "coveralls (1.11.1)", "cython (0.29.17)", "gevent (1.5.0)", "pytest-benchmark (3.2.3)", "pytest-mock (2.0.0)"] +test = ["six (==1.14.0)", "pyannotate (==1.2.0)", "pytest (==4.6.10)", "pytest-django (==3.9.0)", "pytest-cov (==2.8.1)", "coveralls (==1.11.1)", "cython (==0.29.17)", "gevent (==1.5.0)", "pytest-benchmark (==3.2.3)", "pytest-mock (==2.0.0)"] [[package]] -category = "main" -description = "Relay implementation for Python" name = "graphql-relay" +version = "2.0.1" +description = "Relay implementation for Python" +category = "main" optional = false python-versions = "*" -version = "2.0.1" [package.dependencies] graphql-core = ">=2.2,<3" @@ -1067,44 +1046,38 @@ promise = ">=2.2,<3" six = ">=1.12" [[package]] -category = "main" -description = "GRPC library for the google-iam-v1 service" name = "grpc-google-iam-v1" +version = "0.12.3" +description = "GRPC library for the google-iam-v1 service" +category = "main" optional = false python-versions = "*" -version = "0.12.3" [package.dependencies] +googleapis-common-protos = {version = ">=1.5.2,<2.0.0dev", extras = ["grpc"]} grpcio = ">=1.0.0,<2.0.0dev" -[package.dependencies.googleapis-common-protos] -extras = ["grpc"] -version = ">=1.5.2,<2.0.0dev" - [[package]] -category = "main" -description = "HTTP/2-based RPC framework" name = "grpcio" +version = "1.33.2" +description = "HTTP/2-based RPC framework" +category = "main" optional = false python-versions = "*" -version = "1.31.0" [package.dependencies] six = ">=1.5.2" [package.extras] -protobuf = ["grpcio-tools (>=1.31.0)"] +protobuf = ["grpcio-tools (>=1.33.2)"] [[package]] -category = "main" -description = "WSGI HTTP Server for UNIX" name = "gunicorn" +version = "20.0.4" +description = "WSGI HTTP Server for UNIX" +category = "main" optional = false python-versions = ">=3.4" -version = "20.0.4" - -[package.dependencies] -setuptools = ">=3.0" [package.extras] eventlet = ["eventlet (>=0.9.7)"] @@ -1113,20 +1086,20 @@ setproctitle = ["setproctitle"] tornado = ["tornado (>=0.2)"] [[package]] -category = "main" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" name = "h11" +version = "0.11.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +category = "main" optional = false python-versions = "*" -version = "0.9.0" [[package]] -category = "main" -description = "Convert basic HTML into DraftJS JSON format." name = "html-to-draftjs" -optional = false -python-versions = "*" version = "1.0.1" +description = "Convert basic HTML into DraftJS JSON format." +category = "main" +optional = false +python-versions = "*" [package.dependencies] beautifulsoup4 = ">4.7,<4.8" @@ -1136,12 +1109,12 @@ lxml = "*" dev = ["pre-commit", "mock", "pytest"] [[package]] -category = "main" -description = "HTML parser based on the WHATWG HTML specification" name = "html5lib" +version = "1.1" +description = "HTML parser based on the WHATWG HTML specification" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "1.1" [package.dependencies] six = ">=1.9" @@ -1154,51 +1127,50 @@ genshi = ["genshi"] lxml = ["lxml"] [[package]] -category = "main" -description = "A collection of framework independent HTTP protocol utils." -marker = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\"" name = "httptools" +version = "0.1.1" +description = "A collection of framework independent HTTP protocol utils." +category = "main" optional = false python-versions = "*" -version = "0.1.1" [package.extras] -test = ["Cython (0.29.14)"] +test = ["Cython (==0.29.14)"] [[package]] -category = "dev" -description = "File identification library for Python" name = "identify" +version = "1.5.6" +description = "File identification library for Python" +category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -version = "1.4.30" [package.extras] license = ["editdistance"] [[package]] -category = "main" -description = "Internationalized Domain Names in Applications (IDNA)" name = "idna" +version = "2.10" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.10" [[package]] -category = "dev" -description = "iniconfig: brain-dead simple config-ini parsing" name = "iniconfig" +version = "1.1.1" +description = "iniconfig: brain-dead simple config-ini parsing" +category = "dev" optional = false python-versions = "*" -version = "1.0.1" [[package]] -category = "dev" -description = "A Python utility / library to sort Python imports." name = "isort" +version = "4.3.21" +description = "A Python utility / library to sort Python imports." +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "4.3.21" [package.extras] pipfile = ["pipreqs", "requirementslib"] @@ -1207,12 +1179,12 @@ requirements = ["pipreqs", "pip-api"] xdg_home = ["appdirs (>=1.4.0)"] [[package]] -category = "main" -description = "Jaeger Python OpenTracing Tracer implementation" name = "jaeger-client" +version = "4.3.0" +description = "Jaeger Python OpenTracing Tracer implementation" +category = "main" optional = false python-versions = "*" -version = "4.3.0" [package.dependencies] opentracing = ">=2.1,<3.0" @@ -1221,23 +1193,23 @@ thrift = "*" tornado = ">=4.3" [package.extras] -tests = ["mock (1.0.1)", "pycurl (>=7.43,<8)", "pytest (>=3.7.0,<3.8.0)", "pytest-cov (2.5.1)", "coverage (<4.4)", "pytest-timeout (1.3.1)", "pytest-tornado", "pytest-benchmark (>=3.0.0rc1,<3.2)", "pytest-localserver", "flake8", "flake8-quotes", "codecov", "opentracing_instrumentation (>=3,<4)", "prometheus_client (0.3.1)", "tchannel (>=0.27)"] +tests = ["mock (==1.0.1)", "pycurl (>=7.43,<8)", "pytest (>=3.7.0,<3.8.0)", "pytest-cov (==2.5.1)", "coverage (<4.4)", "pytest-timeout (==1.3.1)", "pytest-tornado", "pytest-benchmark[histogram] (>=3.0.0rc1,<3.2)", "pytest-localserver", "flake8", "flake8-quotes", "codecov", "opentracing_instrumentation (>=3,<4)", "prometheus_client (==0.3.1)", "tchannel (>=0.27)"] [[package]] -category = "main" -description = "Julian dates from proleptic Gregorian and Julian calendars." name = "jdcal" +version = "1.4.1" +description = "Julian dates from proleptic Gregorian and Julian calendars." +category = "main" optional = false python-versions = "*" -version = "1.4.1" [[package]] -category = "dev" -description = "A very fast and expressive template engine." name = "jinja2" +version = "2.11.2" +description = "A very fast and expressive template engine." +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "2.11.2" [package.dependencies] MarkupSafe = ">=0.23" @@ -1246,31 +1218,31 @@ MarkupSafe = ">=0.23" i18n = ["Babel (>=0.8)"] [[package]] -category = "main" -description = "JSON Matching Expressions" name = "jmespath" +version = "0.10.0" +description = "JSON Matching Expressions" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -version = "0.10.0" [[package]] -category = "main" -description = "A reusable Django field that allows you to store validated JSON in your model." name = "jsonfield" +version = "3.1.0" +description = "A reusable Django field that allows you to store validated JSON in your model." +category = "main" optional = false python-versions = ">=3.6" -version = "3.1.0" [package.dependencies] Django = ">=2.2" [[package]] -category = "main" -description = "Messaging library for Python." name = "kombu" +version = "5.0.2" +description = "Messaging library for Python." +category = "main" optional = false python-versions = ">=3.6" -version = "5.0.2" [package.dependencies] amqp = ">=5.0.0,<6.0.0" @@ -1287,25 +1259,25 @@ qpid = ["qpid-python (>=0.26)", "qpid-tools (>=0.26)"] redis = ["redis (>=3.3.11)"] slmq = ["softlayer-messaging (>=1.0.3)"] sqlalchemy = ["sqlalchemy"] -sqs = ["boto3 (>=1.4.4)", "pycurl (7.43.0.2)"] +sqs = ["boto3 (>=1.4.4)", "pycurl (==7.43.0.2)"] yaml = ["PyYAML (>=3.10)"] zookeeper = ["kazoo (>=1.3.1)"] [[package]] -category = "dev" -description = "A fast and thorough lazy object proxy." name = "lazy-object-proxy" +version = "1.4.3" +description = "A fast and thorough lazy object proxy." +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.4.3" [[package]] -category = "main" -description = "A concrete syntax tree with AST-like properties for Python 3.5, 3.6, 3.7 and 3.8 programs." name = "libcst" +version = "0.3.13" +description = "A concrete syntax tree with AST-like properties for Python 3.5, 3.6, 3.7 and 3.8 programs." +category = "main" optional = false python-versions = ">=3.6" -version = "0.3.10" [package.dependencies] pyyaml = ">=5.2" @@ -1313,15 +1285,15 @@ typing-extensions = ">=3.7.4.2" typing-inspect = ">=0.4.0" [package.extras] -dev = ["black", "codecov", "coverage", "hypothesis (>=4.36.0)", "hypothesmith (>=0.0.4)", "isort", "flake8", "jupyter", "nbsphinx", "pyre-check", "sphinx", "sphinx-rtd-theme"] +dev = ["black (>=19.10b0)", "codecov (>=2.1.4)", "coverage (>=4.5.4)", "fixit (>=0.1.0)", "flake8 (>=3.7.8)", "hypothesis (>=4.36.0)", "hypothesmith (>=0.0.4)", "isort (>=4.3.20)", "jupyter (>=1.0.0)", "nbsphinx (>=0.4.2)", "pyre-check (==0.0.41)", "sphinx-rtd-theme (>=0.4.3)", "prompt-toolkit (>=2.0.9)", "tox (>=3.18.1)"] [[package]] -category = "main" -description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." name = "lxml" +version = "4.6.1" +description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" -version = "4.5.2" [package.extras] cssselect = ["cssselect (>=0.7)"] @@ -1330,86 +1302,85 @@ htmlsoup = ["beautifulsoup4"] source = ["Cython (>=0.29.7)"] [[package]] -category = "main" -description = "Python implementation of Markdown." name = "markdown" +version = "3.3.3" +description = "Python implementation of Markdown." +category = "main" optional = false -python-versions = ">=3.5" -version = "3.2.2" +python-versions = ">=3.6" [package.extras] testing = ["coverage", "pyyaml"] [[package]] -category = "dev" -description = "Safely add untrusted strings to HTML/XML markup." name = "markupsafe" +version = "1.1.1" +description = "Safely add untrusted strings to HTML/XML markup." +category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -version = "1.1.1" [[package]] -category = "main" -description = "Reader for the MaxMind DB format" name = "maxminddb" +version = "2.0.3" +description = "Reader for the MaxMind DB format" +category = "main" optional = false python-versions = ">=3.6" -version = "2.0.2" [[package]] -category = "main" -description = "Provides access to the geolite2 database. This product includes GeoLite2 data created by MaxMind, available from http://www.maxmind.com/" name = "maxminddb-geolite2" +version = "2018.703" +description = "Provides access to the geolite2 database. This product includes GeoLite2 data created by MaxMind, available from http://www.maxmind.com/" +category = "main" optional = false python-versions = "*" -version = "2018.703" [package.dependencies] maxminddb = "*" [[package]] -category = "dev" -description = "McCabe checker, plugin for flake8" name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +category = "dev" optional = false python-versions = "*" -version = "0.6.1" [[package]] -category = "main" -description = "Easily use and manipulate unit-aware measurements in Python" name = "measurement" +version = "3.2.0" +description = "Easily use and manipulate unit-aware measurements in Python" +category = "main" optional = false python-versions = "*" -version = "3.2.0" [package.dependencies] sympy = ">=0.7.3" [[package]] -category = "main" -description = "Python library for arbitrary-precision floating-point arithmetic" name = "mpmath" +version = "1.1.0" +description = "Python library for arbitrary-precision floating-point arithmetic" +category = "main" optional = false python-versions = "*" -version = "1.1.0" [[package]] -category = "dev" -description = "multidict implementation" -marker = "python_version >= \"3.6\"" name = "multidict" +version = "5.0.0" +description = "multidict implementation" +category = "dev" optional = false python-versions = ">=3.5" -version = "4.7.6" [[package]] -category = "dev" -description = "Optional static typing for Python" name = "mypy" +version = "0.740" +description = "Optional static typing for Python" +category = "dev" optional = false python-versions = ">=3.5" -version = "0.740" [package.dependencies] mypy-extensions = ">=0.4.0,<0.5.0" @@ -1420,28 +1391,28 @@ typing-extensions = ">=3.7.4" dmypy = ["psutil (>=4.0)"] [[package]] -category = "main" -description = "Experimental type system extensions for programs checked with the mypy typechecker." name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "main" optional = false python-versions = "*" -version = "0.4.3" [[package]] -category = "dev" -description = "Node.js virtual environment builder" name = "nodeenv" +version = "1.5.0" +description = "Node.js virtual environment builder" +category = "dev" optional = false python-versions = "*" -version = "1.5.0" [[package]] -category = "main" -description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" name = "oauthlib" +version = "3.1.0" +description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "3.1.0" [package.extras] rsa = ["cryptography"] @@ -1449,55 +1420,55 @@ signals = ["blinker"] signedtoken = ["cryptography", "pyjwt (>=1.0.0)"] [[package]] -category = "main" -description = "A Python library to read/write Excel 2010 xlsx/xlsm files" name = "openpyxl" +version = "3.0.5" +description = "A Python library to read/write Excel 2010 xlsx/xlsm files" +category = "main" optional = false python-versions = ">=3.6," -version = "3.0.5" [package.dependencies] et-xmlfile = "*" jdcal = "*" [[package]] -category = "main" -description = "OpenTracing API for Python. See documentation at http://opentracing.io" name = "opentracing" +version = "2.3.0" +description = "OpenTracing API for Python. See documentation at http://opentracing.io" +category = "main" optional = false python-versions = "*" -version = "2.3.0" [package.extras] tests = ["doubles", "flake8", "flake8-quotes", "mock", "pytest", "pytest-cov", "pytest-mock", "sphinx", "sphinx-rtd-theme", "six (>=1.10.0,<2.0)", "gevent", "tornado"] [[package]] -category = "dev" -description = "Core utilities for Python packages" name = "packaging" +version = "20.4" +description = "Core utilities for Python packages" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "20.4" [package.dependencies] pyparsing = ">=2.0.2" six = "*" [[package]] -category = "dev" -description = "Utility library for gitignore style pattern matching of file paths." name = "pathspec" +version = "0.8.0" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "0.8.0" [[package]] -category = "main" -description = "A Python package for extracting, transforming and loading tables of data." name = "petl" +version = "1.6.7" +description = "A Python package for extracting, transforming and loading tables of data." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.6.7" [package.extras] avro = ["fastavro (>=0.24.0)"] @@ -1516,39 +1487,39 @@ xlsx = ["openpyxl (>=2.6.2)"] xpath = ["lxml (>=4.4.0)"] [[package]] -category = "main" -description = "Python version of Google's common library for parsing, formatting, storing and validating international phone numbers." name = "phonenumberslite" +version = "8.12.11" +description = "Python version of Google's common library for parsing, formatting, storing and validating international phone numbers." +category = "main" optional = false python-versions = "*" -version = "8.12.10" [[package]] -category = "main" -description = "Python Imaging Library (Fork)" name = "pillow" +version = "8.0.1" +description = "Python Imaging Library (Fork)" +category = "main" optional = false -python-versions = ">=3.5" -version = "7.2.0" +python-versions = ">=3.6" [[package]] -category = "dev" -description = "plugin and hook calling mechanisms for python" name = "pluggy" +version = "0.13.1" +description = "plugin and hook calling mechanisms for python" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "0.13.1" [package.extras] dev = ["pre-commit", "tox"] [[package]] -category = "dev" -description = "A framework for managing and maintaining multi-language pre-commit hooks." name = "pre-commit" +version = "2.8.1" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +category = "dev" optional = false python-versions = ">=3.6.1" -version = "2.7.1" [package.dependencies] cfgv = ">=2.0.0" @@ -1559,23 +1530,23 @@ toml = "*" virtualenv = ">=20.0.8" [[package]] -category = "main" -description = "Python price handling for humans" name = "prices" +version = "1.1.0" +description = "Python price handling for humans" +category = "main" optional = false python-versions = "*" -version = "1.1.0" [package.dependencies] babel = ">=2.5.0" [[package]] -category = "main" -description = "Promises/A+ implementation for Python" name = "promise" +version = "2.3" +description = "Promises/A+ implementation for Python" +category = "main" optional = false python-versions = "*" -version = "2.3" [package.dependencies] six = "*" @@ -1584,127 +1555,129 @@ six = "*" test = ["pytest (>=2.7.3)", "pytest-cov", "coveralls", "futures", "pytest-benchmark", "mock"] [[package]] -category = "main" -description = "Library for building powerful interactive command lines in Python" name = "prompt-toolkit" +version = "3.0.8" +description = "Library for building powerful interactive command lines in Python" +category = "main" optional = false python-versions = ">=3.6.1" -version = "3.0.7" [package.dependencies] wcwidth = "*" [[package]] -category = "main" -description = "Beautiful, Pythonic protocol buffers." name = "proto-plus" +version = "1.11.0" +description = "Beautiful, Pythonic protocol buffers." +category = "main" optional = false python-versions = "*" -version = "1.9.1" [package.dependencies] protobuf = ">=3.12.0" +[package.extras] +testing = ["google-api-core[grpc] (>=1.22.2)"] + [[package]] -category = "main" -description = "Protocol Buffers" name = "protobuf" +version = "3.13.0" +description = "Protocol Buffers" +category = "main" optional = false python-versions = "*" -version = "3.13.0" [package.dependencies] -setuptools = "*" six = ">=1.9" [[package]] -category = "main" -description = "psycopg2 - Python-PostgreSQL Database Adapter" name = "psycopg2-binary" +version = "2.8.6" +description = "psycopg2 - Python-PostgreSQL Database Adapter" +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -version = "2.8.6" [[package]] -category = "main" -description = "An immutable URL class for easy URL-building and manipulation" name = "purl" +version = "1.5" +description = "An immutable URL class for easy URL-building and manipulation" +category = "main" optional = false python-versions = "*" -version = "1.5" [package.dependencies] six = "*" [[package]] -category = "dev" -description = "library with cross-python path, ini-parsing, io, code, log facilities" name = "py" +version = "1.9.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.9.0" [[package]] -category = "main" -description = "ASN.1 types and codecs" name = "pyasn1" +version = "0.4.8" +description = "ASN.1 types and codecs" +category = "main" optional = false python-versions = "*" -version = "0.4.8" [[package]] -category = "main" -description = "A collection of ASN.1-based protocols modules." name = "pyasn1-modules" +version = "0.2.8" +description = "A collection of ASN.1-based protocols modules." +category = "main" optional = false python-versions = "*" -version = "0.2.8" [package.dependencies] pyasn1 = ">=0.4.6,<0.5.0" [[package]] -category = "dev" -description = "Python style guide checker" name = "pycodestyle" +version = "2.6.0" +description = "Python style guide checker" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.6.0" [[package]] -category = "main" -description = "C parser in Python" name = "pycparser" +version = "2.20" +description = "C parser in Python" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.20" [[package]] -category = "dev" -description = "Python docstring style checker" name = "pydocstyle" +version = "5.1.1" +description = "Python docstring style checker" +category = "dev" optional = false python-versions = ">=3.5" -version = "5.1.1" [package.dependencies] snowballstemmer = "*" [[package]] -category = "dev" -description = "passive checker of Python programs" name = "pyflakes" +version = "2.2.0" +description = "passive checker of Python programs" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.2.0" [[package]] -category = "main" -description = "JSON Web Token implementation in Python" name = "pyjwt" +version = "1.7.1" +description = "JSON Web Token implementation in Python" +category = "main" optional = false python-versions = "*" -version = "1.7.1" [package.extras] crypto = ["cryptography (>=1.4)"] @@ -1712,27 +1685,27 @@ flake8 = ["flake8", "flake8-import-order", "pep8-naming"] test = ["pytest (>=4.0.1,<5.0.0)", "pytest-cov (>=2.6.0,<3.0.0)", "pytest-runner (>=4.2,<5.0.0)"] [[package]] -category = "dev" -description = "python code static checker" name = "pylint" +version = "2.6.0" +description = "python code static checker" +category = "dev" optional = false python-versions = ">=3.5.*" -version = "2.6.0" [package.dependencies] astroid = ">=2.4.0,<=2.5" -colorama = "*" +colorama = {version = "*", markers = "sys_platform == \"win32\""} isort = ">=4.2.5,<6" mccabe = ">=0.6,<0.7" toml = ">=0.7.1" [[package]] -category = "dev" -description = "pylint-celery is a Pylint plugin to aid Pylint in recognising and understandingerrors caused when using the Celery library" name = "pylint-celery" +version = "0.3" +description = "pylint-celery is a Pylint plugin to aid Pylint in recognising and understandingerrors caused when using the Celery library" +category = "dev" optional = false python-versions = "*" -version = "0.3" [package.dependencies] astroid = ">=1.0" @@ -1740,12 +1713,12 @@ pylint = ">=1.0" pylint-plugin-utils = ">=0.2.1" [[package]] -category = "dev" -description = "A Pylint plugin to help Pylint understand the Django web framework" name = "pylint-django" +version = "2.3.0" +description = "A Pylint plugin to help Pylint understand the Django web framework" +category = "dev" optional = false python-versions = "*" -version = "2.3.0" [package.dependencies] pylint = ">=2.0" @@ -1756,44 +1729,44 @@ for_tests = ["coverage", "django-tables2", "factory-boy", "pytest"] with_django = ["django"] [[package]] -category = "dev" -description = "Utilities and helpers for writing Pylint plugins" name = "pylint-plugin-utils" +version = "0.6" +description = "Utilities and helpers for writing Pylint plugins" +category = "dev" optional = false python-versions = "*" -version = "0.6" [package.dependencies] pylint = ">=1.7" [[package]] -category = "dev" -description = "Python parsing module" name = "pyparsing" +version = "2.4.7" +description = "Python parsing module" +category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -version = "2.4.7" [[package]] -category = "main" -description = "Pure Python module to hyphenate text" name = "pyphen" +version = "0.9.5" +description = "Pure Python module to hyphenate text" +category = "main" optional = false python-versions = "*" -version = "0.9.5" [[package]] -category = "dev" -description = "pytest: simple powerful testing with Python" name = "pytest" +version = "6.1.2" +description = "pytest: simple powerful testing with Python" +category = "dev" optional = false python-versions = ">=3.5" -version = "6.1.1" [package.dependencies] -atomicwrites = ">=1.0" +atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} attrs = ">=17.4.0" -colorama = "*" +colorama = {version = "*", markers = "sys_platform == \"win32\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<1.0" @@ -1801,42 +1774,42 @@ py = ">=1.8.2" toml = "*" [package.extras] -checkqa_mypy = ["mypy (0.780)"] +checkqa_mypy = ["mypy (==0.780)"] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] [[package]] -category = "main" -description = "pytest-celery a shim pytest plugin to enable celery.contrib.pytest" name = "pytest-celery" +version = "0.0.0a1" +description = "pytest-celery a shim pytest plugin to enable celery.contrib.pytest" +category = "dev" optional = false python-versions = "*" -version = "0.0.0a1" [package.dependencies] celery = ">=4.4.0" [[package]] -category = "dev" -description = "Pytest plugin for measuring coverage." name = "pytest-cov" +version = "2.10.1" +description = "Pytest plugin for measuring coverage." +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "2.10.1" [package.dependencies] coverage = ">=4.4" pytest = ">=4.6" [package.extras] -testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "pytest-xdist", "virtualenv"] +testing = ["fields", "hunter", "process-tests (==2.0.2)", "six", "pytest-xdist", "virtualenv"] [[package]] -category = "dev" -description = "A Django plugin for pytest." name = "pytest-django" +version = "3.10.0" +description = "A Django plugin for pytest." +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "3.10.0" [package.dependencies] pytest = ">=3.6" @@ -1846,46 +1819,43 @@ docs = ["sphinx", "sphinx-rtd-theme"] testing = ["django", "django-configurations (>=2.0)", "six"] [[package]] -category = "dev" -description = "Generate performance reports from your django database performance tests." name = "pytest-django-queries" +version = "1.1.0" +description = "Generate performance reports from your django database performance tests." +category = "dev" optional = false python-versions = "*" -version = "1.1.0" [package.dependencies] -Click = "*" beautifultable = "0.7.0" +Click = "*" colorama = "*" +django = {version = "*", markers = "python_version >= \"3.0\""} jinja2 = "*" pytest = ">=4.4.0" -[package.dependencies.django] -python = ">=3.0" -version = "*" - [package.extras] dev = ["beautifulsoup4", "lxml", "sphinx", "sphinx-rtd-theme", "pre-commit", "mock"] [[package]] -category = "dev" -description = "run tests in isolated forked subprocesses" name = "pytest-forked" +version = "1.3.0" +description = "run tests in isolated forked subprocesses" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "1.3.0" [package.dependencies] py = "*" pytest = ">=3.10" [[package]] -category = "dev" -description = "Thin-wrapper around the mock package for easier use with pytest" name = "pytest-mock" +version = "3.3.1" +description = "Thin-wrapper around the mock package for easier use with pytest" +category = "dev" optional = false python-versions = ">=3.5" -version = "3.3.1" [package.dependencies] pytest = ">=5.0" @@ -1894,24 +1864,24 @@ pytest = ">=5.0" dev = ["pre-commit", "tox", "pytest-asyncio"] [[package]] -category = "dev" -description = "Plugin for managing VCR.py cassettes" name = "pytest-vcr" +version = "1.0.2" +description = "Plugin for managing VCR.py cassettes" +category = "dev" optional = false python-versions = "*" -version = "1.0.2" [package.dependencies] pytest = ">=3.6.0" vcrpy = "*" [[package]] -category = "dev" -description = "pytest xdist plugin for distributed testing and loop-on-failing modes" name = "pytest-xdist" +version = "1.34.0" +description = "pytest xdist plugin for distributed testing and loop-on-failing modes" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "1.34.0" [package.dependencies] execnet = ">=1.1" @@ -1923,48 +1893,58 @@ six = "*" testing = ["filelock"] [[package]] -category = "main" -description = "Extensions to the standard Python datetime module" name = "python-dateutil" +version = "2.8.1" +description = "Extensions to the standard Python datetime module" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -version = "2.8.1" [package.dependencies] six = ">=1.5" [[package]] +name = "python-dotenv" +version = "0.15.0" +description = "Add .env support to your django/flask apps in development and deployments" category = "main" -description = "A python library adding a json log formatter" +optional = false +python-versions = "*" + +[package.extras] +cli = ["click (>=5.0)"] + +[[package]] name = "python-json-logger" +version = "2.0.1" +description = "A python library adding a json log formatter" +category = "main" optional = false python-versions = ">=3.4" -version = "2.0.0" [[package]] -category = "main" -description = "File type identification using libmagic" name = "python-magic" +version = "0.4.18" +description = "File type identification using libmagic" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "0.4.18" [[package]] -category = "main" -description = "File type identification using libmagic binary package" -marker = "sys_platform == \"win32\"" name = "python-magic-bin" +version = "0.4.14" +description = "File type identification using libmagic binary package" +category = "main" optional = false python-versions = "*" -version = "0.4.14" [[package]] -category = "dev" -description = "A Python Slugify application that handles Unicode" name = "python-slugify" +version = "4.0.1" +description = "A Python Slugify application that handles Unicode" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "4.0.1" [package.dependencies] text-unidecode = ">=1.3" @@ -1973,74 +1953,74 @@ text-unidecode = ">=1.3" unidecode = ["Unidecode (>=1.1.1)"] [[package]] -category = "main" -description = "Time expression parser" name = "pytimeparse" +version = "1.1.8" +description = "Time expression parser" +category = "main" optional = false python-versions = "*" -version = "1.1.8" -[[package]] -category = "main" -description = "World timezone definitions, modern and historical" +[[package]] name = "pytz" +version = "2020.1" +description = "World timezone definitions, modern and historical" +category = "main" optional = false python-versions = "*" -version = "2020.1" [[package]] -category = "dev" -description = "Watchman client for python" name = "pywatchman" +version = "1.4.1" +description = "Watchman client for python" +category = "dev" optional = false python-versions = "*" -version = "1.4.1" [[package]] -category = "main" -description = "YAML parser and emitter for Python" name = "pyyaml" +version = "5.3.1" +description = "YAML parser and emitter for Python" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "5.3.1" [[package]] -category = "main" -description = "Razorpay Python Client" name = "razorpay" +version = "1.2.0" +description = "Razorpay Python Client" +category = "main" optional = false python-versions = "*" -version = "1.2.0" [package.dependencies] requests = "*" [[package]] -category = "main" -description = "Python client for Redis key-value store" name = "redis" +version = "3.5.3" +description = "Python client for Redis key-value store" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "3.5.3" [package.extras] hiredis = ["hiredis (>=0.1.3)"] [[package]] -category = "dev" -description = "Alternative regular expression module, to replace re." name = "regex" +version = "2020.10.28" +description = "Alternative regular expression module, to replace re." +category = "dev" optional = false python-versions = "*" -version = "2020.7.14" [[package]] -category = "main" -description = "Python HTTP for Humans." name = "requests" +version = "2.24.0" +description = "Python HTTP for Humans." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "2.24.0" [package.dependencies] certifi = ">=2017.4.17" @@ -2050,46 +2030,45 @@ urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" [package.extras] security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] -socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"] +socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] [[package]] -category = "main" -description = "Pure-Python RSA implementation" -marker = "python_version >= \"3.5\"" name = "rsa" +version = "4.6" +description = "Pure-Python RSA implementation" +category = "main" optional = false python-versions = ">=3.5, <4" -version = "4.6" [package.dependencies] pyasn1 = ">=0.1.3" [[package]] -category = "main" -description = "Reactive Extensions (Rx) for Python" name = "rx" +version = "1.6.1" +description = "Reactive Extensions (Rx) for Python" +category = "main" optional = false python-versions = "*" -version = "1.6.1" [[package]] -category = "main" -description = "An Amazon S3 Transfer Manager" name = "s3transfer" +version = "0.3.3" +description = "An Amazon S3 Transfer Manager" +category = "main" optional = false python-versions = "*" -version = "0.3.3" [package.dependencies] botocore = ">=1.12.36,<2.0a.0" [[package]] -category = "main" -description = "Python client for Sentry (https://sentry.io)" name = "sentry-sdk" +version = "0.19.1" +description = "Python client for Sentry (https://sentry.io)" +category = "main" optional = false python-versions = "*" -version = "0.17.3" [package.dependencies] certifi = "*" @@ -2100,6 +2079,7 @@ aiohttp = ["aiohttp (>=3.5)"] beam = ["apache-beam (>=2.12)"] bottle = ["bottle (>=0.12.13)"] celery = ["celery (>=3)"] +chalice = ["chalice (>=1.16.0)"] django = ["django (>=1.8)"] falcon = ["falcon (>=1.4)"] flask = ["flask (>=0.11)", "blinker (>=1.1)"] @@ -2111,106 +2091,104 @@ sqlalchemy = ["sqlalchemy (>=1.2)"] tornado = ["tornado (>=5)"] [[package]] -category = "main" -description = "This library brings functools.singledispatch from Python 3.4 to Python 2.6-3.3." name = "singledispatch" +version = "3.4.0.3" +description = "This library brings functools.singledispatch from Python 3.4 to Python 2.6-3.3." +category = "main" optional = false python-versions = "*" -version = "3.4.0.3" [package.dependencies] six = "*" [[package]] -category = "main" -description = "Python 2 and 3 compatibility utilities" name = "six" +version = "1.15.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -version = "1.15.0" [[package]] -category = "dev" -description = "A pure Python implementation of a sliding window memory map manager" name = "smmap" +version = "3.0.4" +description = "A pure Python implementation of a sliding window memory map manager" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "3.0.4" [[package]] -category = "dev" -description = "This package provides 26 stemmers for 25 languages generated from Snowball algorithms." name = "snowballstemmer" +version = "2.0.0" +description = "This package provides 26 stemmers for 25 languages generated from Snowball algorithms." +category = "dev" optional = false python-versions = "*" -version = "2.0.0" [[package]] -category = "main" -description = "A modern CSS selector implementation for Beautiful Soup." name = "soupsieve" +version = "2.0.1" +description = "A modern CSS selector implementation for Beautiful Soup." +category = "main" optional = false python-versions = ">=3.5" -version = "2.0.1" [[package]] -category = "main" -description = "Non-validating SQL parser" name = "sqlparse" +version = "0.4.1" +description = "A non-validating SQL parser." +category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "0.3.1" +python-versions = ">=3.5" [[package]] -category = "main" -description = "Python bindings for the Stripe API" name = "stripe" +version = "2.55.0" +description = "Python bindings for the Stripe API" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.54.0" [package.dependencies] -[package.dependencies.requests] -python = ">=3.0" -version = ">=2.20" +requests = {version = ">=2.20", markers = "python_version >= \"3.0\""} [[package]] -category = "main" -description = "Computer algebra system (CAS) in Python" name = "sympy" +version = "1.6.2" +description = "Computer algebra system (CAS) in Python" +category = "main" optional = false python-versions = ">=3.5" -version = "1.6.2" [package.dependencies] mpmath = ">=0.19" [[package]] -category = "main" -description = "The most basic Text::Unidecode port" name = "text-unidecode" +version = "1.3" +description = "The most basic Text::Unidecode port" +category = "main" optional = false python-versions = "*" -version = "1.3" [[package]] -category = "main" -description = "Tornado IOLoop Backed Concurrent Futures" name = "threadloop" +version = "1.0.2" +description = "Tornado IOLoop Backed Concurrent Futures" +category = "main" optional = false python-versions = "*" -version = "1.0.2" [package.dependencies] tornado = "*" [[package]] -category = "main" -description = "Python bindings for the Apache Thrift RPC system" name = "thrift" +version = "0.13.0" +description = "Python bindings for the Apache Thrift RPC system" +category = "main" optional = false python-versions = "*" -version = "0.13.0" [package.dependencies] six = ">=1.7.2" @@ -2221,15 +2199,14 @@ tornado = ["tornado (>=4.0)"] twisted = ["twisted"] [[package]] -category = "main" -description = "Low-level CSS parser for Python" name = "tinycss2" +version = "1.0.2" +description = "Low-level CSS parser for Python" +category = "main" optional = false python-versions = ">= 3.5" -version = "1.0.2" [package.dependencies] -setuptools = ">=39.2.0" webencodings = ">=0.4" [package.extras] @@ -2237,31 +2214,31 @@ doc = ["sphinx", "sphinx-rtd-theme"] test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"] [[package]] -category = "dev" -description = "Python Library for Tom's Obvious, Minimal Language" name = "toml" +version = "0.10.1" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "dev" optional = false python-versions = "*" -version = "0.10.1" [[package]] -category = "main" -description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." name = "tornado" +version = "6.0.4" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +category = "main" optional = false python-versions = ">= 3.5" -version = "6.0.4" [[package]] -category = "dev" -description = "tox is a generic virtualenv management and test command line tool" name = "tox" +version = "3.20.1" +description = "tox is a generic virtualenv management and test command line tool" +category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -version = "3.20.0" [package.dependencies] -colorama = ">=0.4.1" +colorama = {version = ">=0.4.1", markers = "platform_system == \"Windows\""} filelock = ">=3.0.0" packaging = ">=14" pluggy = ">=0.12.0" @@ -2275,23 +2252,23 @@ docs = ["pygments-github-lexers (>=0.0.5)", "sphinx (>=2.0.0)", "sphinxcontrib-a testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pathlib2 (>=2.3.3)", "psutil (>=5.6.1)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-randomly (>=1.0.0)", "pytest-xdist (>=1.22.2)"] [[package]] -category = "main" -description = "Fast, Extensible Progress Meter" name = "tqdm" +version = "4.51.0" +description = "Fast, Extensible Progress Meter" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*" -version = "4.50.0" [package.extras] dev = ["py-make (>=0.1.0)", "twine", "argopt", "pydoc-markdown"] [[package]] -category = "dev" -description = "A command line interface for Transifex" name = "transifex-client" +version = "0.14.1" +description = "A command line interface for Transifex" +category = "dev" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,<3.9" -version = "0.13.12" +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,<3.10" [package.dependencies] gitpython = "<4.0.0" @@ -2301,113 +2278,113 @@ six = "<2.0.0" urllib3 = ">=1.24.2,<2.0.0" [[package]] -category = "dev" -description = "a fork of Python 2 and 3 ast modules with type comment support" name = "typed-ast" +version = "1.4.1" +description = "a fork of Python 2 and 3 ast modules with type comment support" +category = "dev" optional = false python-versions = "*" -version = "1.4.1" [[package]] -category = "main" -description = "Backported and Experimental Type Hints for Python 3.5+" name = "typing-extensions" +version = "3.7.4.3" +description = "Backported and Experimental Type Hints for Python 3.5+" +category = "main" optional = false python-versions = "*" -version = "3.7.4.3" [[package]] -category = "main" -description = "Runtime inspection utilities for typing module." name = "typing-inspect" +version = "0.6.0" +description = "Runtime inspection utilities for typing module." +category = "main" optional = false python-versions = "*" -version = "0.6.0" [package.dependencies] mypy-extensions = ">=0.3.0" typing-extensions = ">=3.7.4" [[package]] -category = "main" -description = "ASCII transliterations of Unicode text" name = "unidecode" +version = "1.1.1" +description = "ASCII transliterations of Unicode text" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.1.1" [[package]] -category = "main" -description = "HTTP library with thread-safe connection pooling, file post, and more." name = "urllib3" +version = "1.25.11" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" -version = "1.25.10" [package.extras] brotli = ["brotlipy (>=0.6.0)"] -secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)", "ipaddress"] -socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] -category = "main" -description = "The lightning-fast ASGI server." name = "uvicorn" +version = "0.12.2" +description = "The lightning-fast ASGI server." +category = "main" optional = false python-versions = "*" -version = "0.11.8" [package.dependencies] click = ">=7.0.0,<8.0.0" -h11 = ">=0.8,<0.10" -httptools = ">=0.1.0,<0.2.0" -uvloop = ">=0.14.0" -websockets = ">=8.0.0,<9.0.0" +colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""} +h11 = ">=0.8" +httptools = {version = ">=0.1.0,<0.2.0", optional = true, markers = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\" and extra == \"standard\""} +python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} +PyYAML = {version = ">=5.1", optional = true, markers = "extra == \"standard\""} +uvloop = {version = ">=0.14.0", optional = true, markers = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\" and extra == \"standard\""} +watchgod = {version = ">=0.6,<0.7", optional = true, markers = "extra == \"standard\""} +websockets = {version = ">=8.0.0,<9.0.0", optional = true, markers = "extra == \"standard\""} [package.extras] -watchgodreload = ["watchgod (>=0.6,<0.7)"] +standard = ["websockets (>=8.0.0,<9.0.0)", "watchgod (>=0.6,<0.7)", "python-dotenv (>=0.13)", "PyYAML (>=5.1)", "httptools (>=0.1.0,<0.2.0)", "uvloop (>=0.14.0)", "colorama (>=0.4)"] [[package]] -category = "main" -description = "Fast implementation of asyncio event loop on top of libuv" -marker = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\"" name = "uvloop" +version = "0.14.0" +description = "Fast implementation of asyncio event loop on top of libuv" +category = "main" optional = false python-versions = "*" -version = "0.14.0" [[package]] -category = "dev" -description = "Automatically mock your HTTP interactions to simplify and speed up testing" name = "vcrpy" +version = "4.1.1" +description = "Automatically mock your HTTP interactions to simplify and speed up testing" +category = "dev" optional = false python-versions = ">=3.5" -version = "4.1.0" [package.dependencies] PyYAML = "*" six = ">=1.5" wrapt = "*" - -[package.dependencies.yarl] -python = ">=3.6" -version = "*" +yarl = {version = "*", markers = "python_version >= \"3.6\""} [[package]] -category = "main" -description = "Promises, promises, promises." name = "vine" +version = "5.0.0" +description = "Promises, promises, promises." +category = "main" optional = false python-versions = ">=3.6" -version = "5.0.0" [[package]] -category = "dev" -description = "Virtual Python Environment builder" name = "virtualenv" +version = "20.1.0" +description = "Virtual Python Environment builder" +category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -version = "20.0.31" [package.dependencies] appdirs = ">=1.4.3,<2" @@ -2417,32 +2394,39 @@ six = ">=1.9.0,<2" [package.extras] docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)"] -testing = ["coverage (>=5)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "pytest-xdist (>=1.31.0)", "packaging (>=20.0)", "xonsh (>=0.9.16)"] +testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "pytest-xdist (>=1.31.0)", "packaging (>=20.0)", "xonsh (>=0.9.16)"] [[package]] +name = "watchgod" +version = "0.6" +description = "Simple, modern file watching and code reload in python." category = "main" -description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = ">=3.5" + +[[package]] name = "wcwidth" +version = "0.2.5" +description = "Measures the displayed width of unicode strings in a terminal" +category = "main" optional = false python-versions = "*" -version = "0.2.5" [[package]] -category = "main" -description = "The Awesome Document Factory" name = "weasyprint" +version = "51" +description = "The Awesome Document Factory" +category = "main" optional = false python-versions = ">=3.5" -version = "51" [package.dependencies] -CairoSVG = ">=2.4.0" -Pyphen = ">=0.9.1" cairocffi = ">=0.9.0" +CairoSVG = ">=2.4.0" cffi = ">=0.6" cssselect2 = ">=0.1" html5lib = ">=0.999999999" -setuptools = ">=39.2.0" +Pyphen = ">=0.9.1" tinycss2 = ">=1.0.0" [package.extras] @@ -2450,46 +2434,45 @@ doc = ["sphinx", "sphinx-rtd-theme"] test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"] [[package]] -category = "main" -description = "Character encoding aliases for legacy web content" name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +category = "main" optional = false python-versions = "*" -version = "0.5.1" [[package]] -category = "main" -description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" name = "websockets" +version = "8.1" +description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +category = "main" optional = false python-versions = ">=3.6.1" -version = "8.1" [[package]] -category = "dev" -description = "Module for decorators, wrappers and monkey patching." name = "wrapt" +version = "1.12.1" +description = "Module for decorators, wrappers and monkey patching." +category = "dev" optional = false python-versions = "*" -version = "1.12.1" [[package]] -category = "dev" -description = "Yet another URL library" -marker = "python_version >= \"3.6\"" name = "yarl" +version = "1.6.2" +description = "Yet another URL library" +category = "dev" optional = false -python-versions = ">=3.5" -version = "1.5.1" +python-versions = ">=3.6" [package.dependencies] idna = ">=2.0" multidict = ">=4.0" [metadata] -content-hash = "72d7bfda7c8f4cb90deedc7825371caa0069ed603b6b8be1a817b28fd4a647bc" -lock-version = "1.0" +lock-version = "1.1" python-versions = "~3.8" +content-hash = "8c71d5d1e209ff1e1bb0ce7725db548fda72940c2195641612213cad67baf096" [metadata.files] adyen = [ @@ -2524,8 +2507,8 @@ atomicwrites = [ {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, ] attrs = [ - {file = "attrs-20.1.0-py2.py3-none-any.whl", hash = "sha256:2867b7b9f8326499ab5b0e2d12801fa5c98842d2cbd22b35112ae04bf85b4dff"}, - {file = "attrs-20.1.0.tar.gz", hash = "sha256:0ef97238856430dcf9228e07f316aefc17e8939fc8507e18c6501b761ef1a42a"}, + {file = "attrs-20.2.0-py2.py3-none-any.whl", hash = "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc"}, + {file = "attrs-20.2.0.tar.gz", hash = "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594"}, ] babel = [ {file = "Babel-2.8.0-py2.py3-none-any.whl", hash = "sha256:d670ea0b10f8b723672d3a6abeb87b565b244da220d76b4dba1b66269ec152d4"}, @@ -2549,12 +2532,12 @@ black = [ {file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"}, ] boto3 = [ - {file = "boto3-1.15.11-py2.py3-none-any.whl", hash = "sha256:5f3969dd167b787e5bc6742afbfe15e149051d8c6aa1edaa4858133384f64ec7"}, - {file = "boto3-1.15.11.tar.gz", hash = "sha256:713da2b28e9e4cd77e922690c97935dd2316ab27635b6bab4745a2d42bd887ec"}, + {file = "boto3-1.16.7-py2.py3-none-any.whl", hash = "sha256:b378c28c2db3be96abc2ca460c2f08424da8960b87d5d430cb7d6b712ec255b2"}, + {file = "boto3-1.16.7.tar.gz", hash = "sha256:2cabcdc217a128832d6c948cae22cbd3af03ae0736efcb59749f1f11f528be54"}, ] botocore = [ - {file = "botocore-1.18.11-py2.py3-none-any.whl", hash = "sha256:a0514ba531148af26fe36bf75c73089698a5ed8ae150695b96e7cbdf32dd232b"}, - {file = "botocore-1.18.11.tar.gz", hash = "sha256:1531ee5d7f7d0f0d9a12ea829ef046ac52063a1948409ae19a452a3f47a07937"}, + {file = "botocore-1.19.7-py2.py3-none-any.whl", hash = "sha256:1481d6d3ccb77cb7cd97395110408238f3ab93b0d823156c7a2fb697604eb50d"}, + {file = "botocore-1.19.7.tar.gz", hash = "sha256:ab59f842797cbd09ee7d9e3f353bb9546f428853d94db448977dd554320620b3"}, ] braintree = [ {file = "braintree-4.4.0-py2.py3-none-any.whl", hash = "sha256:10b99ea6ea482d1438b0d058dbe51f6a33fe98fe6d0d977d4b7c5868fe3b9e35"}, @@ -2572,42 +2555,50 @@ cairosvg = [ {file = "CairoSVG-2.4.2.tar.gz", hash = "sha256:4e668f96653326780036ebb0a9ff2bb59a8443d7bcfc51a14aab77b57a8e67ad"}, ] celery = [ - {file = "celery-5.0.0-py3-none-any.whl", hash = "sha256:72138dc3887f68dc58e1a2397e477256f80f1894c69fa4337f8ed70be460375b"}, - {file = "celery-5.0.0.tar.gz", hash = "sha256:313930fddde703d8e37029a304bf91429cd11aeef63c57de6daca9d958e1f255"}, + {file = "celery-5.0.1-py3-none-any.whl", hash = "sha256:7aa4ee46ed318bc177900ae7c01500354aee62d723255b0925db0754bcd4d390"}, + {file = "celery-5.0.1.tar.gz", hash = "sha256:e3e8956d74af986b1e9770e0a294338b259618bf70283d6157416328e50c2bd6"}, ] certifi = [ {file = "certifi-2020.6.20-py2.py3-none-any.whl", hash = "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"}, {file = "certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"}, ] cffi = [ - {file = "cffi-1.14.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:da9d3c506f43e220336433dffe643fbfa40096d408cb9b7f2477892f369d5f82"}, - {file = "cffi-1.14.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23e44937d7695c27c66a54d793dd4b45889a81b35c0751ba91040fe825ec59c4"}, - {file = "cffi-1.14.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:0da50dcbccd7cb7e6c741ab7912b2eff48e85af217d72b57f80ebc616257125e"}, - {file = "cffi-1.14.2-cp27-cp27m-win32.whl", hash = "sha256:76ada88d62eb24de7051c5157a1a78fd853cca9b91c0713c2e973e4196271d0c"}, - {file = "cffi-1.14.2-cp27-cp27m-win_amd64.whl", hash = "sha256:15a5f59a4808f82d8ec7364cbace851df591c2d43bc76bcbe5c4543a7ddd1bf1"}, - {file = "cffi-1.14.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:e4082d832e36e7f9b2278bc774886ca8207346b99f278e54c9de4834f17232f7"}, - {file = "cffi-1.14.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:57214fa5430399dffd54f4be37b56fe22cedb2b98862550d43cc085fb698dc2c"}, - {file = "cffi-1.14.2-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:6843db0343e12e3f52cc58430ad559d850a53684f5b352540ca3f1bc56df0731"}, - {file = "cffi-1.14.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:577791f948d34d569acb2d1add5831731c59d5a0c50a6d9f629ae1cefd9ca4a0"}, - {file = "cffi-1.14.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:8662aabfeab00cea149a3d1c2999b0731e70c6b5bac596d95d13f643e76d3d4e"}, - {file = "cffi-1.14.2-cp35-cp35m-win32.whl", hash = "sha256:837398c2ec00228679513802e3744d1e8e3cb1204aa6ad408b6aff081e99a487"}, - {file = "cffi-1.14.2-cp35-cp35m-win_amd64.whl", hash = "sha256:bf44a9a0141a082e89c90e8d785b212a872db793a0080c20f6ae6e2a0ebf82ad"}, - {file = "cffi-1.14.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:29c4688ace466a365b85a51dcc5e3c853c1d283f293dfcc12f7a77e498f160d2"}, - {file = "cffi-1.14.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:99cc66b33c418cd579c0f03b77b94263c305c389cb0c6972dac420f24b3bf123"}, - {file = "cffi-1.14.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:65867d63f0fd1b500fa343d7798fa64e9e681b594e0a07dc934c13e76ee28fb1"}, - {file = "cffi-1.14.2-cp36-cp36m-win32.whl", hash = "sha256:f5033952def24172e60493b68717792e3aebb387a8d186c43c020d9363ee7281"}, - {file = "cffi-1.14.2-cp36-cp36m-win_amd64.whl", hash = "sha256:7057613efefd36cacabbdbcef010e0a9c20a88fc07eb3e616019ea1692fa5df4"}, - {file = "cffi-1.14.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6539314d84c4d36f28d73adc1b45e9f4ee2a89cdc7e5d2b0a6dbacba31906798"}, - {file = "cffi-1.14.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:672b539db20fef6b03d6f7a14b5825d57c98e4026401fce838849f8de73fe4d4"}, - {file = "cffi-1.14.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:95e9094162fa712f18b4f60896e34b621df99147c2cee216cfa8f022294e8e9f"}, - {file = "cffi-1.14.2-cp37-cp37m-win32.whl", hash = "sha256:b9aa9d8818c2e917fa2c105ad538e222a5bce59777133840b93134022a7ce650"}, - {file = "cffi-1.14.2-cp37-cp37m-win_amd64.whl", hash = "sha256:e4b9b7af398c32e408c00eb4e0d33ced2f9121fd9fb978e6c1b57edd014a7d15"}, - {file = "cffi-1.14.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e613514a82539fc48291d01933951a13ae93b6b444a88782480be32245ed4afa"}, - {file = "cffi-1.14.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:9b219511d8b64d3fa14261963933be34028ea0e57455baf6781fe399c2c3206c"}, - {file = "cffi-1.14.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c0b48b98d79cf795b0916c57bebbc6d16bb43b9fc9b8c9f57f4cf05881904c75"}, - {file = "cffi-1.14.2-cp38-cp38-win32.whl", hash = "sha256:15419020b0e812b40d96ec9d369b2bc8109cc3295eac6e013d3261343580cc7e"}, - {file = "cffi-1.14.2-cp38-cp38-win_amd64.whl", hash = "sha256:12a453e03124069b6896107ee133ae3ab04c624bb10683e1ed1c1663df17c13c"}, - {file = "cffi-1.14.2.tar.gz", hash = "sha256:ae8f34d50af2c2154035984b8b5fc5d9ed63f32fe615646ab435b05b132ca91b"}, + {file = "cffi-1.14.3-2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3eeeb0405fd145e714f7633a5173318bd88d8bbfc3dd0a5751f8c4f70ae629bc"}, + {file = "cffi-1.14.3-2-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:cb763ceceae04803adcc4e2d80d611ef201c73da32d8f2722e9d0ab0c7f10768"}, + {file = "cffi-1.14.3-2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:44f60519595eaca110f248e5017363d751b12782a6f2bd6a7041cba275215f5d"}, + {file = "cffi-1.14.3-2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c53af463f4a40de78c58b8b2710ade243c81cbca641e34debf3396a9640d6ec1"}, + {file = "cffi-1.14.3-2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:33c6cdc071ba5cd6d96769c8969a0531be2d08c2628a0143a10a7dcffa9719ca"}, + {file = "cffi-1.14.3-2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c11579638288e53fc94ad60022ff1b67865363e730ee41ad5e6f0a17188b327a"}, + {file = "cffi-1.14.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:3cb3e1b9ec43256c4e0f8d2837267a70b0e1ca8c4f456685508ae6106b1f504c"}, + {file = "cffi-1.14.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:f0620511387790860b249b9241c2f13c3a80e21a73e0b861a2df24e9d6f56730"}, + {file = "cffi-1.14.3-cp27-cp27m-win32.whl", hash = "sha256:005f2bfe11b6745d726dbb07ace4d53f057de66e336ff92d61b8c7e9c8f4777d"}, + {file = "cffi-1.14.3-cp27-cp27m-win_amd64.whl", hash = "sha256:2f9674623ca39c9ebe38afa3da402e9326c245f0f5ceff0623dccdac15023e05"}, + {file = "cffi-1.14.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:09e96138280241bd355cd585148dec04dbbedb4f46128f340d696eaafc82dd7b"}, + {file = "cffi-1.14.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:3363e77a6176afb8823b6e06db78c46dbc4c7813b00a41300a4873b6ba63b171"}, + {file = "cffi-1.14.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:0ef488305fdce2580c8b2708f22d7785ae222d9825d3094ab073e22e93dfe51f"}, + {file = "cffi-1.14.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:0b1ad452cc824665ddc682400b62c9e4f5b64736a2ba99110712fdee5f2505c4"}, + {file = "cffi-1.14.3-cp35-cp35m-win32.whl", hash = "sha256:85ba797e1de5b48aa5a8427b6ba62cf69607c18c5d4eb747604b7302f1ec382d"}, + {file = "cffi-1.14.3-cp35-cp35m-win_amd64.whl", hash = "sha256:e66399cf0fc07de4dce4f588fc25bfe84a6d1285cc544e67987d22663393926d"}, + {file = "cffi-1.14.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:15f351bed09897fbda218e4db5a3d5c06328862f6198d4fb385f3e14e19decb3"}, + {file = "cffi-1.14.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4d7c26bfc1ea9f92084a1d75e11999e97b62d63128bcc90c3624d07813c52808"}, + {file = "cffi-1.14.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:23e5d2040367322824605bc29ae8ee9175200b92cb5483ac7d466927a9b3d537"}, + {file = "cffi-1.14.3-cp36-cp36m-win32.whl", hash = "sha256:a624fae282e81ad2e4871bdb767e2c914d0539708c0f078b5b355258293c98b0"}, + {file = "cffi-1.14.3-cp36-cp36m-win_amd64.whl", hash = "sha256:de31b5164d44ef4943db155b3e8e17929707cac1e5bd2f363e67a56e3af4af6e"}, + {file = "cffi-1.14.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f92cdecb618e5fa4658aeb97d5eb3d2f47aa94ac6477c6daf0f306c5a3b9e6b1"}, + {file = "cffi-1.14.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:22399ff4870fb4c7ef19fff6eeb20a8bbf15571913c181c78cb361024d574579"}, + {file = "cffi-1.14.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f4eae045e6ab2bb54ca279733fe4eb85f1effda392666308250714e01907f394"}, + {file = "cffi-1.14.3-cp37-cp37m-win32.whl", hash = "sha256:b0358e6fefc74a16f745afa366acc89f979040e0cbc4eec55ab26ad1f6a9bfbc"}, + {file = "cffi-1.14.3-cp37-cp37m-win_amd64.whl", hash = "sha256:6642f15ad963b5092d65aed022d033c77763515fdc07095208f15d3563003869"}, + {file = "cffi-1.14.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:2791f68edc5749024b4722500e86303a10d342527e1e3bcac47f35fbd25b764e"}, + {file = "cffi-1.14.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:529c4ed2e10437c205f38f3691a68be66c39197d01062618c55f74294a4a4828"}, + {file = "cffi-1.14.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8f0f1e499e4000c4c347a124fa6a27d37608ced4fe9f7d45070563b7c4c370c9"}, + {file = "cffi-1.14.3-cp38-cp38-win32.whl", hash = "sha256:3b8eaf915ddc0709779889c472e553f0d3e8b7bdf62dab764c8921b09bf94522"}, + {file = "cffi-1.14.3-cp38-cp38-win_amd64.whl", hash = "sha256:bbd2f4dfee1079f76943767fce837ade3087b578aeb9f69aec7857d5bf25db15"}, + {file = "cffi-1.14.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:cc75f58cdaf043fe6a7a6c04b3b5a0e694c6a9e24050967747251fb80d7bce0d"}, + {file = "cffi-1.14.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:bf39a9e19ce7298f1bd6a9758fa99707e9e5b1ebe5e90f2c3913a47bc548747c"}, + {file = "cffi-1.14.3-cp39-cp39-win32.whl", hash = "sha256:d80998ed59176e8cba74028762fbd9b9153b9afc71ea118e63bbf5d4d0f9552b"}, + {file = "cffi-1.14.3-cp39-cp39-win_amd64.whl", hash = "sha256:c150eaa3dadbb2b5339675b88d4573c1be3cb6f2c33a6c83387e10cc0bf05bd3"}, + {file = "cffi-1.14.3.tar.gz", hash = "sha256:f92f789e4f9241cd262ad7a555ca2c648a98178a953af117ef7fad46aa1d5591"}, ] cfgv = [ {file = "cfgv-3.2.0-py2.py3-none-any.whl", hash = "sha256:32e43d604bbe7896fe7c248a9c2276447dbef840feb28fe20494f62af110211d"}, @@ -2629,13 +2620,13 @@ click-repl = [ {file = "click_repl-0.1.6-py3-none-any.whl", hash = "sha256:9c4c3d022789cae912aad8a3f5e1d7c2cdd016ee1225b5212ad3e8691563cda5"}, ] codecov = [ - {file = "codecov-2.1.9-py2.py3-none-any.whl", hash = "sha256:24545847177a893716b3455ac5bfbafe0465f38d4eb86ea922c09adc7f327e65"}, - {file = "codecov-2.1.9-py3.8.egg", hash = "sha256:7877f68effde3c2baadcff807a5d13f01019a337f9596eece0d64e57393adf3a"}, - {file = "codecov-2.1.9.tar.gz", hash = "sha256:355fc7e0c0b8a133045f0d6089bde351c845e7b52b99fec5903b4ea3ab5f6aab"}, + {file = "codecov-2.1.10-py2.py3-none-any.whl", hash = "sha256:61bc71b5f58be8000bf9235aa9d0112f8fd3acca00aa02191bb81426d22a8584"}, + {file = "codecov-2.1.10-py3.8.egg", hash = "sha256:a333626e6ff882db760ce71a1d84baf80ddff2cd459a3cc49b41fdac47d77ca5"}, + {file = "codecov-2.1.10.tar.gz", hash = "sha256:d30ad6084501224b1ba699cbf018a340bb9553eb2701301c14133995fdd84f33"}, ] colorama = [ - {file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"}, - {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] coverage = [ {file = "coverage-5.3-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:bd3166bb3b111e76a4f8e2980fa1addf2920a4ca9b2b8ca36a3bc3dedc618270"}, @@ -2761,7 +2752,8 @@ django-redis = [ {file = "django_redis-4.12.1-py3-none-any.whl", hash = "sha256:1133b26b75baa3664164c3f44b9d5d133d1b8de45d94d79f38d1adc5b1d502e5"}, ] django-render-block = [ - {file = "django_render_block-0.7-py3-none-any.whl", hash = "sha256:3e5963a2332727ca0db2bb8ca031404fba3ac9024702446eed5b7fb02209f7f3"}, + {file = "django-render-block-0.8.1.tar.gz", hash = "sha256:edbc5d444cc50f3eb3387cf17f6f1014bf19d6018f680861cdeae9e0306003fa"}, + {file = "django_render_block-0.8.1-py3-none-any.whl", hash = "sha256:903969efd0949f750c5fe71affe6e6b1ea66d03005c102a67fda36d5b9f4e1e1"}, ] django-storages = [ {file = "django-storages-1.10.1.tar.gz", hash = "sha256:652275ab7844538c462b62810276c0244866f345878256a9e0e86f5b1283ae18"}, @@ -2793,8 +2785,8 @@ execnet = [ {file = "execnet-1.7.1.tar.gz", hash = "sha256:cacb9df31c9680ec5f95553976c4da484d407e85e41c83cb812aa014f0eddc50"}, ] faker = [ - {file = "Faker-4.1.3-py3-none-any.whl", hash = "sha256:80bab8d46035a7393de827210c5d39c17109d3346d131946bde622137120c496"}, - {file = "Faker-4.1.3.tar.gz", hash = "sha256:075a95ac4c95765370919d787dcd958acfaea635005ad5af4d926cb0973800db"}, + {file = "Faker-4.14.0-py3-none-any.whl", hash = "sha256:a7a36c3c657f06bd1e3e3821b9480f2a92017d8a26e150e464ab6b97743cbc92"}, + {file = "Faker-4.14.0.tar.gz", hash = "sha256:30afa8f564350770373f299d2d267bff42aaba699a7ae0a3b6f378b2a8170569"}, ] filelock = [ {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"}, @@ -2813,28 +2805,28 @@ gitdb = [ {file = "gitdb-4.0.5.tar.gz", hash = "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9"}, ] gitpython = [ - {file = "GitPython-3.1.7-py3-none-any.whl", hash = "sha256:fa3b92da728a457dd75d62bb5f3eb2816d99a7fe6c67398e260637a40e3fafb5"}, - {file = "GitPython-3.1.7.tar.gz", hash = "sha256:2db287d71a284e22e5c2846042d0602465c7434d910406990d5b74df4afb0858"}, + {file = "GitPython-3.1.11-py3-none-any.whl", hash = "sha256:6eea89b655917b500437e9668e4a12eabdcf00229a0df1762aabd692ef9b746b"}, + {file = "GitPython-3.1.11.tar.gz", hash = "sha256:befa4d101f91bad1b632df4308ec64555db684c360bd7d2130b4807d49ce86b8"}, ] google-api-core = [ - {file = "google-api-core-1.22.2.tar.gz", hash = "sha256:779107f17e0fef8169c5239d56a8fbff03f9f72a3893c0c9e5842ec29dfedd54"}, - {file = "google_api_core-1.22.2-py2.py3-none-any.whl", hash = "sha256:67e33a852dcca7cb7eff49abc35c8cc2c0bb8ab11397dc8306d911505cae2990"}, + {file = "google-api-core-1.23.0.tar.gz", hash = "sha256:1bb3c485c38eacded8d685b1759968f6cf47dd9432922d34edb90359eaa391e2"}, + {file = "google_api_core-1.23.0-py2.py3-none-any.whl", hash = "sha256:94d8c707d358d8d9e8b0045c42be20efb58433d308bd92cf748511c7825569c8"}, ] google-auth = [ - {file = "google-auth-1.21.3.tar.gz", hash = "sha256:31941bf019fb242c04d0de32845da10180788bfddb0de87d78c4bdf55555dda1"}, - {file = "google_auth-1.21.3-py2.py3-none-any.whl", hash = "sha256:873051a6317294b083795cffc467bcd05b6df483ef542bfe0069ddbfbac0a096"}, + {file = "google-auth-1.22.1.tar.gz", hash = "sha256:9c0f71789438d703f77b94aad4ea545afaec9a65f10e6cc1bc8b89ce242244bb"}, + {file = "google_auth-1.22.1-py2.py3-none-any.whl", hash = "sha256:712dd7d140a9a1ea218e5688c7fcb04af71b431a29ec9ce433e384c60e387b98"}, ] google-cloud-core = [ - {file = "google-cloud-core-1.4.1.tar.gz", hash = "sha256:613e56f164b6bee487dd34f606083a0130f66f42f7b10f99730afdf1630df507"}, - {file = "google_cloud_core-1.4.1-py2.py3-none-any.whl", hash = "sha256:4c9e457fcfc026fdde2e492228f04417d4c717fb0f29f070122fb0ab89e34ebd"}, + {file = "google-cloud-core-1.4.3.tar.gz", hash = "sha256:21afb70c1b0bce8eeb8abb5dca63c5fd37fc8aea18f4b6d60e803bd3d27e6b80"}, + {file = "google_cloud_core-1.4.3-py2.py3-none-any.whl", hash = "sha256:75abff9056977809937127418323faa3917f32df68490704d39a4f0d492ebc2b"}, ] google-cloud-pubsub = [ {file = "google-cloud-pubsub-2.1.0.tar.gz", hash = "sha256:42b07d8652f0ff0d118430a04abc19ee1f6fd85ccbfe86fcbb01bf487079a80c"}, {file = "google_cloud_pubsub-2.1.0-py2.py3-none-any.whl", hash = "sha256:84ba7485cf036b38bc3b1b146504dd39922a1dc719d6845809d7b2d0e1ede624"}, ] google-cloud-storage = [ - {file = "google-cloud-storage-1.31.2.tar.gz", hash = "sha256:74bbb5b2d0b249de4a52f561435d0c3570ddc19b249653ae588ec0abcc3c81e6"}, - {file = "google_cloud_storage-1.31.2-py2.py3-none-any.whl", hash = "sha256:e2a2533b5e368365e84d2acaa53b75266a09802fc1c8bda52e3212335eccb6bd"}, + {file = "google-cloud-storage-1.32.0.tar.gz", hash = "sha256:da12b7bd79bbe978a7945a44b600604fbc10ece2935d31f243e751f99135e34f"}, + {file = "google_cloud_storage-1.32.0-py2.py3-none-any.whl", hash = "sha256:063bd12b5ceb4045e8681dc5cce8c3ceeb1203f7c5c3e59f5c9b75bb79a5f59b"}, ] google-crc32c = [ {file = "google-crc32c-1.0.0.tar.gz", hash = "sha256:9439b960b6ecd847557675d130fc3626d762bf535da595c20a6949a705fb3eae"}, @@ -2865,8 +2857,8 @@ google-measurement-protocol = [ {file = "google_measurement_protocol-1.1.0-py2.py3-none-any.whl", hash = "sha256:387800809d143bf490353e19d78bf856066875fdad80817d9f148219c483f087"}, ] google-resumable-media = [ - {file = "google-resumable-media-1.0.0.tar.gz", hash = "sha256:173acc6bade1480a529fa29c6c2717543ae2dc09d42e9461fdb86f39502efcf2"}, - {file = "google_resumable_media-1.0.0-py2.py3-none-any.whl", hash = "sha256:99b5ac33a75ddb25d5e6aad487b37ecb4fa18b1fbf3d1ad726e032c3d6fc9aff"}, + {file = "google-resumable-media-1.1.0.tar.gz", hash = "sha256:dcdab13e95bc534d268f87d5293e482cce5bc86dfce6ca0f2e2e89cbb73ef38c"}, + {file = "google_resumable_media-1.1.0-py2.py3-none-any.whl", hash = "sha256:ecabcd90d74a6e00331af0c87f500f238c44870d9626e01b385dda3af7b99269"}, ] googleapis-common-protos = [ {file = "googleapis-common-protos-1.52.0.tar.gz", hash = "sha256:560716c807117394da12cecb0a54da5a451b5cf9866f1d37e9a5e2329a665351"}, @@ -2895,53 +2887,58 @@ grpc-google-iam-v1 = [ {file = "grpc-google-iam-v1-0.12.3.tar.gz", hash = "sha256:0bfb5b56f648f457021a91c0df0db4934b6e0c300bd0f2de2333383fe958aa72"}, ] grpcio = [ - {file = "grpcio-1.31.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:e8c3264b0fd728aadf3f0324471843f65bd3b38872bdab2a477e31ffb685dd5b"}, - {file = "grpcio-1.31.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:5fb0923b16590bac338e92d98c7d8effb3cfad1d2e18c71bf86bde32c49cd6dd"}, - {file = "grpcio-1.31.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:58d7121f48cb94535a4cedcce32921d0d0a78563c7372a143dedeec196d1c637"}, - {file = "grpcio-1.31.0-cp27-cp27m-win32.whl", hash = "sha256:ea849210e7362559f326cbe603d5b8d8bb1e556e86a7393b5a8847057de5b084"}, - {file = "grpcio-1.31.0-cp27-cp27m-win_amd64.whl", hash = "sha256:ba3e43cb984399064ffaa3c0997576e46a1e268f9da05f97cd9b272f0b59ee71"}, - {file = "grpcio-1.31.0-cp27-cp27mu-linux_armv7l.whl", hash = "sha256:ebb2ca09fa17537e35508a29dcb05575d4d9401138a68e83d1c605d65e8a1770"}, - {file = "grpcio-1.31.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:292635f05b6ce33f87116951d0b3d8d330bdfc5cac74f739370d60981e8c256c"}, - {file = "grpcio-1.31.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:92e54ab65e782f227e751c7555918afaba8d1229601687e89b80c2b65d2f6642"}, - {file = "grpcio-1.31.0-cp35-cp35m-linux_armv7l.whl", hash = "sha256:013287f99c99b201aa8a5f6bc7918f616739b9be031db132d9e3b8453e95e151"}, - {file = "grpcio-1.31.0-cp35-cp35m-macosx_10_7_intel.whl", hash = "sha256:d2c5e05c257859febd03f5d81b5015e1946d6bcf475c7bf63ee99cea8ab0d590"}, - {file = "grpcio-1.31.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:c9016ab1eaf4e054099303287195f3746bd4e69f2631d040f9dca43e910a5408"}, - {file = "grpcio-1.31.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:baaa036540d7ace433bdf38a3fe5e41cf9f84cdf10a88bac805f678a7ca8ddcc"}, - {file = "grpcio-1.31.0-cp35-cp35m-manylinux2014_i686.whl", hash = "sha256:75e383053dccb610590aa53eed5278db5c09bf498d3b5105ce6c776478f59352"}, - {file = "grpcio-1.31.0-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:739a72abffbd36083ff7adbb862cf1afc1e311c35834bed9c0361d8e68b063e1"}, - {file = "grpcio-1.31.0-cp35-cp35m-win32.whl", hash = "sha256:f04c59d186af3157dc8811114130aaeae92e90a65283733f41de94eed484e1f7"}, - {file = "grpcio-1.31.0-cp35-cp35m-win_amd64.whl", hash = "sha256:ef9fce98b6fe03874c2a6576b02aec1a0df25742cd67d1d7b75a49e30aa74225"}, - {file = "grpcio-1.31.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:08a9b648dbe8852ff94b73a1c96da126834c3057ba2301d13e8c4adff334c482"}, - {file = "grpcio-1.31.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c22b19abba63562a5a200e586b5bde39d26c8ec30c92e26d209d81182371693b"}, - {file = "grpcio-1.31.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:0397616355760cd8282ed5ea34d51830ae4cb6613b7e5f66bed3be5d041b8b9a"}, - {file = "grpcio-1.31.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:259240aab2603891553e17ad5b2655693df79e02a9b887ff605bdeb2fcd3dcc9"}, - {file = "grpcio-1.31.0-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:8ca26b489b5dc1e3d31807d329c23d6cb06fe40fbae25b0649b718947936e26a"}, - {file = "grpcio-1.31.0-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:bf39977282a79dc1b2765cc3402c0ada571c29a491caec6ed12c0993c1ec115e"}, - {file = "grpcio-1.31.0-cp36-cp36m-win32.whl", hash = "sha256:f5b0870b733bcb7b6bf05a02035e7aaf20f599d3802b390282d4c2309f825f1d"}, - {file = "grpcio-1.31.0-cp36-cp36m-win_amd64.whl", hash = "sha256:074871a184483d5cd0746fd01e7d214d3ee9d36e67e32a5786b0a21f29fb8304"}, - {file = "grpcio-1.31.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:220c46b1fc9c9a6fcca4caac398f08f0ed43cdd63c45b7458983c4a1575ef6df"}, - {file = "grpcio-1.31.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:7a11b1ebb3210f34913b8be6995936bf9ebc541a65ab69e75db5ce1fe5047e8f"}, - {file = "grpcio-1.31.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:3c2aa6d7a5e5bf73fdb1715eee777efe06dd39df03383f1cc095b2fdb34883e6"}, - {file = "grpcio-1.31.0-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:e64bddd09842ef508d72ca354319b0eb126205d951e8ac3128fe9869bd563552"}, - {file = "grpcio-1.31.0-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:5d7faa89992e015d245750ca9ac916c161bbf72777b2c60abc61da3fae41339e"}, - {file = "grpcio-1.31.0-cp37-cp37m-win32.whl", hash = "sha256:43d44548ad6ee738b941abd9f09e3b83a5c13f3e1410321023c3c148ba50e796"}, - {file = "grpcio-1.31.0-cp37-cp37m-win_amd64.whl", hash = "sha256:bf00ab06ea4f89976288f4d6224d4aa120780e30c955d4f85c3214ada29b3ddf"}, - {file = "grpcio-1.31.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:344b50865914cc8e6d023457bffee9a640abb18f75d0f2bb519041961c748da9"}, - {file = "grpcio-1.31.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:63ee8e02d04272c3d103f44b4bce5d43ea757dd288673cea212d2f7da27967d2"}, - {file = "grpcio-1.31.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:a9a7ae74cb3108e6457cf15532d4c300324b48fbcf3ef290bcd2835745f20510"}, - {file = "grpcio-1.31.0-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:64077e3a9a7cf2f59e6c76d503c8de1f18a76428f41a5b000dc53c48a0b772ff"}, - {file = "grpcio-1.31.0-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:8b42f0ac76be07a5fa31117a3388d754ad35ef05e2e34be185ca9ccbcfac2069"}, - {file = "grpcio-1.31.0-cp38-cp38-win32.whl", hash = "sha256:8002a89ea91c0078c15d3c0daf423fd4968946be78f08545e807ea9a5ff8054a"}, - {file = "grpcio-1.31.0-cp38-cp38-win_amd64.whl", hash = "sha256:0fa86ac4452602c79774783aa68979a1a7625ebb7eaabee2b6550b975b9d61e6"}, - {file = "grpcio-1.31.0.tar.gz", hash = "sha256:5043440c45c0a031f387e7f48527541c65d672005fb24cf18ef6857483557d39"}, + {file = "grpcio-1.33.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c5030be8a60fb18de1fc8d93d130d57e4296c02f229200df814f6578da00429e"}, + {file = "grpcio-1.33.2-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:5b21d3de520a699cb631cfd3a773a57debeb36b131be366bf832153405cc5404"}, + {file = "grpcio-1.33.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:b412f43c99ca72769306293ba83811b241d41b62ca8f358e47e0fdaf7b6fbbd7"}, + {file = "grpcio-1.33.2-cp27-cp27m-win32.whl", hash = "sha256:703da25278ee7318acb766be1c6d3b67d392920d002b2d0304e7f3431b74f6c1"}, + {file = "grpcio-1.33.2-cp27-cp27m-win_amd64.whl", hash = "sha256:2f2eabfd514af8945ee415083a0f849eea6cb3af444999453bb6666fadc10f54"}, + {file = "grpcio-1.33.2-cp27-cp27mu-linux_armv7l.whl", hash = "sha256:d51ddfb3d481a6a3439db09d4b08447fb9f6b60d862ab301238f37bea8f60a6d"}, + {file = "grpcio-1.33.2-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:407b4d869ce5c6a20af5b96bb885e3ecaf383e3fb008375919eb26cf8f10d9cd"}, + {file = "grpcio-1.33.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:abaf30d18874310d4439a23a0afb6e4b5709c4266966401de7c4ae345cc810ee"}, + {file = "grpcio-1.33.2-cp35-cp35m-linux_armv7l.whl", hash = "sha256:f2673c51e8535401c68806d331faba614bcff3ee16373481158a2e74f510b7f6"}, + {file = "grpcio-1.33.2-cp35-cp35m-macosx_10_7_intel.whl", hash = "sha256:65b06fa2db2edd1b779f9b256e270f7a58d60e40121660d8b5fd6e8b88f122ed"}, + {file = "grpcio-1.33.2-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:514b4a6790d6597fc95608f49f2f13fe38329b2058538095f0502b734b98ffd2"}, + {file = "grpcio-1.33.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:4cef3eb2df338abd9b6164427ede961d351c6bf39b4a01448a65f9e795f56575"}, + {file = "grpcio-1.33.2-cp35-cp35m-manylinux2014_i686.whl", hash = "sha256:3ac453387add933b6cfbc67cc8635f91ff9895299130fc612c3c4b904e91d82a"}, + {file = "grpcio-1.33.2-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:7d292dabf7ded9c062357f8207e20e94095a397d487ffd25aa213a2c3dff0ab4"}, + {file = "grpcio-1.33.2-cp35-cp35m-win32.whl", hash = "sha256:0aeed3558a0eec0b31700af6072f1c90e8fd5701427849e76bc469554a14b4f5"}, + {file = "grpcio-1.33.2-cp35-cp35m-win_amd64.whl", hash = "sha256:88f2a102cbc67e91f42b4323cec13348bf6255b25f80426088079872bd4f3c5c"}, + {file = "grpcio-1.33.2-cp36-cp36m-linux_armv7l.whl", hash = "sha256:affbb739fde390710190e3540acc9f3e65df25bd192cc0aa554f368288ee0ea2"}, + {file = "grpcio-1.33.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ffec0b854d2ed6ee98776c7168c778cdd18503642a68d36c00ba0f96d4ccff7c"}, + {file = "grpcio-1.33.2-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:7744468ee48be3265db798f27e66e118c324d7831a34fd39d5775bcd5a70a2c4"}, + {file = "grpcio-1.33.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:6a1b5b7e47600edcaeaa42983b1c19e7a5892c6b98bcde32ae2aa509a99e0436"}, + {file = "grpcio-1.33.2-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:289671cfe441069f617bf23c41b1fa07053a31ff64de918d1016ac73adda2f73"}, + {file = "grpcio-1.33.2-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:a8c84db387907e8d800c383e4c92f39996343adedf635ae5206a684f94df8311"}, + {file = "grpcio-1.33.2-cp36-cp36m-win32.whl", hash = "sha256:4bb771c4c2411196b778871b519c7e12e87f3fa72b0517b22f952c64ead07958"}, + {file = "grpcio-1.33.2-cp36-cp36m-win_amd64.whl", hash = "sha256:b581ddb8df619402c377c81f186ad7f5e2726ad9f8d57047144b352f83f37522"}, + {file = "grpcio-1.33.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:02a4a637a774382d6ac8e65c0a7af4f7f4b9704c980a0a9f4f7bbc1e97c5b733"}, + {file = "grpcio-1.33.2-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:592656b10528aa327058d2007f7ab175dc9eb3754b289e24cac36e09129a2f6b"}, + {file = "grpcio-1.33.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:c89510381cbf8c8317e14e747a8b53988ad226f0ed240824064a9297b65f921d"}, + {file = "grpcio-1.33.2-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:7fda62846ef8d86caf06bd1ecfddcae2c7e59479a4ee28808120e170064d36cc"}, + {file = "grpcio-1.33.2-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:d386630af995fd4de225d550b6806507ca09f5a650f227fddb29299335cda55e"}, + {file = "grpcio-1.33.2-cp37-cp37m-win32.whl", hash = "sha256:bf7de9e847d2d14a0efcd48b290ee181fdbffb2ae54dfa2ec2a935a093730bac"}, + {file = "grpcio-1.33.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7c1ea6ea6daa82031af6eb5b7d1ab56b1193840389ea7cf46d80e98636f8aff5"}, + {file = "grpcio-1.33.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:85e56ab125b35b1373205b3802f58119e70ffedfe0d7e2821999126058f7c44f"}, + {file = "grpcio-1.33.2-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:0cebba3907441d5c620f7b491a780ed155140fbd590da0886ecfb1df6ad947b9"}, + {file = "grpcio-1.33.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:52143467237bfa77331ed1979dc3e203a1c12511ee37b3ddd9ff41b05804fb10"}, + {file = "grpcio-1.33.2-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:8cf67b8493bff50fa12b4bc30ab40ce1f1f216eb54145962b525852959b0ab3d"}, + {file = "grpcio-1.33.2-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:fa78bd55ec652d4a88ba254c8dae623c9992e2ce647bd17ba1a37ca2b7b42222"}, + {file = "grpcio-1.33.2-cp38-cp38-win32.whl", hash = "sha256:143b4fe72c01000fc0667bf62ace402a6518939b3511b3c2bec04d44b1d7591c"}, + {file = "grpcio-1.33.2-cp38-cp38-win_amd64.whl", hash = "sha256:08b6a58c8a83e71af5650f8f879fe14b7b84dce0c4969f3817b42c72989dacf0"}, + {file = "grpcio-1.33.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:56e2a985efdba8e2282e856470b684e83a3cadd920f04fcd360b4b826ced0dd3"}, + {file = "grpcio-1.33.2-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:62ce7e86f11e8c4ff772e63c282fb5a7904274258be0034adf37aa679cf96ba0"}, + {file = "grpcio-1.33.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:7f727b8b6d9f92fcab19dbc62ec956d8352c6767b97b8ab18754b2dfa84d784f"}, + {file = "grpcio-1.33.2-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:2d5124284f9d29e4f06f674a12ebeb23fc16ce0f96f78a80a6036930642ae5ab"}, + {file = "grpcio-1.33.2-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:eff55d318a114742ed2a06972f5daacfe3d5ad0c0c0d9146bcaf10acb427e6be"}, + {file = "grpcio-1.33.2.tar.gz", hash = "sha256:21265511880056d19ce4f809ce3fbe2a3fa98ec1fc7167dbdf30a80d3276202e"}, ] gunicorn = [ {file = "gunicorn-20.0.4-py2.py3-none-any.whl", hash = "sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c"}, {file = "gunicorn-20.0.4.tar.gz", hash = "sha256:1904bb2b8a43658807108d59c3f3d56c2b6121a701161de0ddf9ad140073c626"}, ] h11 = [ - {file = "h11-0.9.0-py2.py3-none-any.whl", hash = "sha256:4bc6d6a1238b7615b266ada57e0618568066f57dd6fa967d1290ec9309b2f2f1"}, - {file = "h11-0.9.0.tar.gz", hash = "sha256:33d4bca7be0fa039f4e84d50ab00531047e53d6ee8ffbc83501ea602c169cae1"}, + {file = "h11-0.11.0-py2.py3-none-any.whl", hash = "sha256:ab6c335e1b6ef34b205d5ca3e228c9299cc7218b049819ec84a388c2525e5d87"}, + {file = "h11-0.11.0.tar.gz", hash = "sha256:3c6c61d69c6f13d41f1b80ab0322f1872702a3ba26e12aa864c928f6a43fbaab"}, ] html-to-draftjs = [ {file = "html-to-draftjs-1.0.1.tar.gz", hash = "sha256:2212acf3b063c17b6dc91875f474159e1f730c1a4e5fbf74f9a66250f7040e9a"}, @@ -2965,16 +2962,16 @@ httptools = [ {file = "httptools-0.1.1.tar.gz", hash = "sha256:41b573cf33f64a8f8f3400d0a7faf48e1888582b6f6e02b82b9bd4f0bf7497ce"}, ] identify = [ - {file = "identify-1.4.30-py2.py3-none-any.whl", hash = "sha256:f9f84a4ff44e29b9cc23c4012c2c8954089860723f80ce63d760393e5f197108"}, - {file = "identify-1.4.30.tar.gz", hash = "sha256:e105a62fd3a496c701fd1bc4e24eb695455b5efb97e722816d5bd988c3344311"}, + {file = "identify-1.5.6-py2.py3-none-any.whl", hash = "sha256:3139bf72d81dfd785b0a464e2776bd59bdc725b4cc10e6cf46b56a0db931c82e"}, + {file = "identify-1.5.6.tar.gz", hash = "sha256:969d844b7a85d32a5f9ac4e163df6e846d73c87c8b75847494ee8f4bd2186421"}, ] idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, ] iniconfig = [ - {file = "iniconfig-1.0.1-py3-none-any.whl", hash = "sha256:80cf40c597eb564e86346103f609d74efce0f6b4d4f30ec8ce9e2c26411ba437"}, - {file = "iniconfig-1.0.1.tar.gz", hash = "sha256:e5f92f89355a67de0595932a6c6c02ab4afddc6fcdc0bfc5becd0d60884d3f69"}, + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] isort = [ {file = "isort-4.3.21-py2.py3-none-any.whl", hash = "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"}, @@ -3027,41 +3024,50 @@ lazy-object-proxy = [ {file = "lazy_object_proxy-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239"}, ] libcst = [ - {file = "libcst-0.3.10-py3-none-any.whl", hash = "sha256:e9395d952a490e6fc160f2bea8df139bdf1fdcb3fe4c01b88893da279eff00de"}, - {file = "libcst-0.3.10.tar.gz", hash = "sha256:b0dccbfc1cff7bfa3214980e1d2d90b4e00b2fed002d4b276a8a411217738df3"}, + {file = "libcst-0.3.13-py3-none-any.whl", hash = "sha256:fc0caad2c7e9be689cadd6eaece9cbfc14378cb5237a80232607dc2c1fa66480"}, + {file = "libcst-0.3.13.tar.gz", hash = "sha256:dc89f56a04ab3fcf30d0a6d5ec6d5328eaed9c7e1f2f82ab91f15c07d9178ace"}, ] lxml = [ - {file = "lxml-4.5.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:74f48ec98430e06c1fa8949b49ebdd8d27ceb9df8d3d1c92e1fdc2773f003f20"}, - {file = "lxml-4.5.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e70d4e467e243455492f5de463b72151cc400710ac03a0678206a5f27e79ddef"}, - {file = "lxml-4.5.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:7ad7906e098ccd30d8f7068030a0b16668ab8aa5cda6fcd5146d8d20cbaa71b5"}, - {file = "lxml-4.5.2-cp27-cp27m-win32.whl", hash = "sha256:92282c83547a9add85ad658143c76a64a8d339028926d7dc1998ca029c88ea6a"}, - {file = "lxml-4.5.2-cp27-cp27m-win_amd64.whl", hash = "sha256:05a444b207901a68a6526948c7cc8f9fe6d6f24c70781488e32fd74ff5996e3f"}, - {file = "lxml-4.5.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:94150231f1e90c9595ccc80d7d2006c61f90a5995db82bccbca7944fd457f0f6"}, - {file = "lxml-4.5.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bea760a63ce9bba566c23f726d72b3c0250e2fa2569909e2d83cda1534c79443"}, - {file = "lxml-4.5.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c3f511a3c58676147c277eff0224c061dd5a6a8e1373572ac817ac6324f1b1e0"}, - {file = "lxml-4.5.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:59daa84aef650b11bccd18f99f64bfe44b9f14a08a28259959d33676554065a1"}, - {file = "lxml-4.5.2-cp35-cp35m-win32.whl", hash = "sha256:9dc9006dcc47e00a8a6a029eb035c8f696ad38e40a27d073a003d7d1443f5d88"}, - {file = "lxml-4.5.2-cp35-cp35m-win_amd64.whl", hash = "sha256:08fc93257dcfe9542c0a6883a25ba4971d78297f63d7a5a26ffa34861ca78730"}, - {file = "lxml-4.5.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:121b665b04083a1e85ff1f5243d4a93aa1aaba281bc12ea334d5a187278ceaf1"}, - {file = "lxml-4.5.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5591c4164755778e29e69b86e425880f852464a21c7bb53c7ea453bbe2633bbe"}, - {file = "lxml-4.5.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:cc411ad324a4486b142c41d9b2b6a722c534096963688d879ea6fa8a35028258"}, - {file = "lxml-4.5.2-cp36-cp36m-win32.whl", hash = "sha256:786aad2aa20de3dbff21aab86b2fb6a7be68064cbbc0219bde414d3a30aa47ae"}, - {file = "lxml-4.5.2-cp36-cp36m-win_amd64.whl", hash = "sha256:e1cacf4796b20865789083252186ce9dc6cc59eca0c2e79cca332bdff24ac481"}, - {file = "lxml-4.5.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:80a38b188d20c0524fe8959c8ce770a8fdf0e617c6912d23fc97c68301bb9aba"}, - {file = "lxml-4.5.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ecc930ae559ea8a43377e8b60ca6f8d61ac532fc57efb915d899de4a67928efd"}, - {file = "lxml-4.5.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a76979f728dd845655026ab991df25d26379a1a8fc1e9e68e25c7eda43004bed"}, - {file = "lxml-4.5.2-cp37-cp37m-win32.whl", hash = "sha256:5a9c8d11aa2c8f8b6043d845927a51eb9102eb558e3f936df494e96393f5fd3e"}, - {file = "lxml-4.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:4b4a111bcf4b9c948e020fd207f915c24a6de3f1adc7682a2d92660eb4e84f1a"}, - {file = "lxml-4.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5dd20538a60c4cc9a077d3b715bb42307239fcd25ef1ca7286775f95e9e9a46d"}, - {file = "lxml-4.5.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:2b30aa2bcff8e958cd85d907d5109820b01ac511eae5b460803430a7404e34d7"}, - {file = "lxml-4.5.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:aa8eba3db3d8761db161003e2d0586608092e217151d7458206e243be5a43843"}, - {file = "lxml-4.5.2-cp38-cp38-win32.whl", hash = "sha256:107781b213cf7201ec3806555657ccda67b1fccc4261fb889ef7fc56976db81f"}, - {file = "lxml-4.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:f161af26f596131b63b236372e4ce40f3167c1b5b5d459b29d2514bd8c9dc9ee"}, - {file = "lxml-4.5.2.tar.gz", hash = "sha256:cdc13a1682b2a6241080745b1953719e7fe0850b40a5c71ca574f090a1391df6"}, + {file = "lxml-4.6.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:4b7572145054330c8e324a72d808c8c8fbe12be33368db28c39a255ad5f7fb51"}, + {file = "lxml-4.6.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:302160eb6e9764168e01d8c9ec6becddeb87776e81d3fcb0d97954dd51d48e0a"}, + {file = "lxml-4.6.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:d4ad7fd3269281cb471ad6c7bafca372e69789540d16e3755dd717e9e5c9d82f"}, + {file = "lxml-4.6.1-cp27-cp27m-win32.whl", hash = "sha256:189ad47203e846a7a4951c17694d845b6ade7917c47c64b29b86526eefc3adf5"}, + {file = "lxml-4.6.1-cp27-cp27m-win_amd64.whl", hash = "sha256:56eff8c6fb7bc4bcca395fdff494c52712b7a57486e4fbde34c31bb9da4c6cc4"}, + {file = "lxml-4.6.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:23c83112b4dada0b75789d73f949dbb4e8f29a0a3511647024a398ebd023347b"}, + {file = "lxml-4.6.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:0e89f5d422988c65e6936e4ec0fe54d6f73f3128c80eb7ecc3b87f595523607b"}, + {file = "lxml-4.6.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2358809cc64394617f2719147a58ae26dac9e21bae772b45cfb80baa26bfca5d"}, + {file = "lxml-4.6.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:be1ebf9cc25ab5399501c9046a7dcdaa9e911802ed0e12b7d620cd4bbf0518b3"}, + {file = "lxml-4.6.1-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:4fff34721b628cce9eb4538cf9a73d02e0f3da4f35a515773cce6f5fe413b360"}, + {file = "lxml-4.6.1-cp35-cp35m-win32.whl", hash = "sha256:475325e037fdf068e0c2140b818518cf6bc4aa72435c407a798b2db9f8e90810"}, + {file = "lxml-4.6.1-cp35-cp35m-win_amd64.whl", hash = "sha256:f98b6f256be6cec8dd308a8563976ddaff0bdc18b730720f6f4bee927ffe926f"}, + {file = "lxml-4.6.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:be7c65e34d1b50ab7093b90427cbc488260e4b3a38ef2435d65b62e9fa3d798a"}, + {file = "lxml-4.6.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:d18331ea905a41ae71596502bd4c9a2998902328bbabd29e3d0f5f8569fabad1"}, + {file = "lxml-4.6.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:3d9b2b72eb0dbbdb0e276403873ecfae870599c83ba22cadff2db58541e72856"}, + {file = "lxml-4.6.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:d20d32cbb31d731def4b1502294ca2ee99f9249b63bc80e03e67e8f8e126dea8"}, + {file = "lxml-4.6.1-cp36-cp36m-win32.whl", hash = "sha256:d182eada8ea0de61a45a526aa0ae4bcd222f9673424e65315c35820291ff299c"}, + {file = "lxml-4.6.1-cp36-cp36m-win_amd64.whl", hash = "sha256:c0dac835c1a22621ffa5e5f999d57359c790c52bbd1c687fe514ae6924f65ef5"}, + {file = "lxml-4.6.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d84d741c6e35c9f3e7406cb7c4c2e08474c2a6441d59322a00dcae65aac6315d"}, + {file = "lxml-4.6.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:8862d1c2c020cb7a03b421a9a7b4fe046a208db30994fc8ff68c627a7915987f"}, + {file = "lxml-4.6.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:3a7a380bfecc551cfd67d6e8ad9faa91289173bdf12e9cfafbd2bdec0d7b1ec1"}, + {file = "lxml-4.6.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:2d6571c48328be4304aee031d2d5046cbc8aed5740c654575613c5a4f5a11311"}, + {file = "lxml-4.6.1-cp37-cp37m-win32.whl", hash = "sha256:803a80d72d1f693aa448566be46ffd70882d1ad8fc689a2e22afe63035eb998a"}, + {file = "lxml-4.6.1-cp37-cp37m-win_amd64.whl", hash = "sha256:24e811118aab6abe3ce23ff0d7d38932329c513f9cef849d3ee88b0f848f2aa9"}, + {file = "lxml-4.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2e311a10f3e85250910a615fe194839a04a0f6bc4e8e5bb5cac221344e3a7891"}, + {file = "lxml-4.6.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:a71400b90b3599eb7bf241f947932e18a066907bf84617d80817998cee81e4bf"}, + {file = "lxml-4.6.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:211b3bcf5da70c2d4b84d09232534ad1d78320762e2c59dedc73bf01cb1fc45b"}, + {file = "lxml-4.6.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:e65c221b2115a91035b55a593b6eb94aa1206fa3ab374f47c6dc10d364583ff9"}, + {file = "lxml-4.6.1-cp38-cp38-win32.whl", hash = "sha256:d6f8c23f65a4bfe4300b85f1f40f6c32569822d08901db3b6454ab785d9117cc"}, + {file = "lxml-4.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:573b2f5496c7e9f4985de70b9bbb4719ffd293d5565513e04ac20e42e6e5583f"}, + {file = "lxml-4.6.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:1d87936cb5801c557f3e981c9c193861264c01209cb3ad0964a16310ca1b3301"}, + {file = "lxml-4.6.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:2d5896ddf5389560257bbe89317ca7bcb4e54a02b53a3e572e1ce4226512b51b"}, + {file = "lxml-4.6.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:9b06690224258db5cd39a84e993882a6874676f5de582da57f3df3a82ead9174"}, + {file = "lxml-4.6.1-cp39-cp39-win32.whl", hash = "sha256:bb252f802f91f59767dcc559744e91efa9df532240a502befd874b54571417bd"}, + {file = "lxml-4.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ecaef52fd9b9535ae5f01a1dd2651f6608e4ec9dc136fc4dfe7ebe3c3ddb230"}, + {file = "lxml-4.6.1.tar.gz", hash = "sha256:c152b2e93b639d1f36ec5a8ca24cde4a8eefb2b6b83668fcd8e83a67badcb367"}, ] markdown = [ - {file = "Markdown-3.2.2-py3-none-any.whl", hash = "sha256:c467cd6233885534bf0fe96e62e3cf46cfc1605112356c4f9981512b8174de59"}, - {file = "Markdown-3.2.2.tar.gz", hash = "sha256:1fafe3f1ecabfb514a5285fca634a53c1b32a81cb0feb154264d55bf2ff22c17"}, + {file = "Markdown-3.3.3-py3-none-any.whl", hash = "sha256:c109c15b7dc20a9ac454c9e6025927d44460b85bd039da028d85e2b6d0bcc328"}, + {file = "Markdown-3.3.3.tar.gz", hash = "sha256:5d9f2b5ca24bc4c7a390d22323ca4bad200368612b5aaa7796babf971d2b2f18"}, ] markupsafe = [ {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, @@ -3099,7 +3105,7 @@ markupsafe = [ {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, ] maxminddb = [ - {file = "maxminddb-2.0.2.tar.gz", hash = "sha256:b95d8ed21799e6604683669c7ed3c6a184fcd92434d5762dccdb139b4f29e597"}, + {file = "maxminddb-2.0.3.tar.gz", hash = "sha256:47e86a084dd814fac88c99ea34ba3278a74bc9de5a25f4b815b608798747c7dc"}, ] maxminddb-geolite2 = [ {file = "maxminddb-geolite2-2018.703.tar.gz", hash = "sha256:2bd118c5567f3a8323d6c5da23a6e6d52cfc09cd9987b54eb712cf6001a96e03"}, @@ -3115,23 +3121,39 @@ mpmath = [ {file = "mpmath-1.1.0.tar.gz", hash = "sha256:fc17abe05fbab3382b61a123c398508183406fa132e0223874578e20946499f6"}, ] multidict = [ - {file = "multidict-4.7.6-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:275ca32383bc5d1894b6975bb4ca6a7ff16ab76fa622967625baeebcf8079000"}, - {file = "multidict-4.7.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:1ece5a3369835c20ed57adadc663400b5525904e53bae59ec854a5d36b39b21a"}, - {file = "multidict-4.7.6-cp35-cp35m-win32.whl", hash = "sha256:5141c13374e6b25fe6bf092052ab55c0c03d21bd66c94a0e3ae371d3e4d865a5"}, - {file = "multidict-4.7.6-cp35-cp35m-win_amd64.whl", hash = "sha256:9456e90649005ad40558f4cf51dbb842e32807df75146c6d940b6f5abb4a78f3"}, - {file = "multidict-4.7.6-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:e0d072ae0f2a179c375f67e3da300b47e1a83293c554450b29c900e50afaae87"}, - {file = "multidict-4.7.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:3750f2205b800aac4bb03b5ae48025a64e474d2c6cc79547988ba1d4122a09e2"}, - {file = "multidict-4.7.6-cp36-cp36m-win32.whl", hash = "sha256:f07acae137b71af3bb548bd8da720956a3bc9f9a0b87733e0899226a2317aeb7"}, - {file = "multidict-4.7.6-cp36-cp36m-win_amd64.whl", hash = "sha256:6513728873f4326999429a8b00fc7ceddb2509b01d5fd3f3be7881a257b8d463"}, - {file = "multidict-4.7.6-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d"}, - {file = "multidict-4.7.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255"}, - {file = "multidict-4.7.6-cp37-cp37m-win32.whl", hash = "sha256:4538273208e7294b2659b1602490f4ed3ab1c8cf9dbdd817e0e9db8e64be2507"}, - {file = "multidict-4.7.6-cp37-cp37m-win_amd64.whl", hash = "sha256:d14842362ed4cf63751648e7672f7174c9818459d169231d03c56e84daf90b7c"}, - {file = "multidict-4.7.6-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:c026fe9a05130e44157b98fea3ab12969e5b60691a276150db9eda71710cd10b"}, - {file = "multidict-4.7.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:51a4d210404ac61d32dada00a50ea7ba412e6ea945bbe992e4d7a595276d2ec7"}, - {file = "multidict-4.7.6-cp38-cp38-win32.whl", hash = "sha256:5cf311a0f5ef80fe73e4f4c0f0998ec08f954a6ec72b746f3c179e37de1d210d"}, - {file = "multidict-4.7.6-cp38-cp38-win_amd64.whl", hash = "sha256:7388d2ef3c55a8ba80da62ecfafa06a1c097c18032a501ffd4cabbc52d7f2b19"}, - {file = "multidict-4.7.6.tar.gz", hash = "sha256:fbb77a75e529021e7c4a8d4e823d88ef4d23674a202be4f5addffc72cbb91430"}, + {file = "multidict-5.0.0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:11dcf2366da487d5b9de1d4b2055308c7ed9bde1a52973d07a89b42252af9ebe"}, + {file = "multidict-5.0.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:167bd8e6351b57525bbf2d524ca5a133834699a2fcb090aad0c330c6017f3f3e"}, + {file = "multidict-5.0.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:60af726c19a899ed49bbb276e062f08b80222cb6b9feda44b59a128b5ff52966"}, + {file = "multidict-5.0.0-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:32f0a904859a6274d7edcbb01752c8ae9c633fb7d1c131771ff5afd32eceee42"}, + {file = "multidict-5.0.0-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:7561a804093ea4c879e06b5d3d18a64a0bc21004bade3540a4b31342b528d326"}, + {file = "multidict-5.0.0-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:786ad04ad954afe9927a1b3049aa58722e182160fe2fcac7ad7f35c93595d4f6"}, + {file = "multidict-5.0.0-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:02b2ea2bb1277a970d238c5c783023790ca94d386c657aeeb165259950951cc6"}, + {file = "multidict-5.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:932964cf57c0e59d1f3fb63ff342440cf8aaa75bf0dbcbad902c084024975380"}, + {file = "multidict-5.0.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:c692087913e12b801a759e25a626c3d311f416252dfba2ecdfd254583427949f"}, + {file = "multidict-5.0.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:cda06c99cd6f4a36571bb38e560a6fcfb1f136521e57f612e0bc31957b1cd4bd"}, + {file = "multidict-5.0.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:84e4943d8725659942e7401bdf31780acde9cfdaf6fe977ff1449fffafcd93a9"}, + {file = "multidict-5.0.0-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:bbec545b8f82536bc50afa9abce832176ed250aa22bfff3e20b3463fb90b0b35"}, + {file = "multidict-5.0.0-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:c339b7d73c0ea5c551025617bb8aa1c00a0111187b6545f48836343e6cfbe6a0"}, + {file = "multidict-5.0.0-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:0ce1d956ecbf112d49915ebc2f29c03e35fe451fb5e9f491edf9a2f4395ee0af"}, + {file = "multidict-5.0.0-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:39713fa2c687e0d0e709ad751a8a709ac051fcdc7f2048f6fd09365dd03c83eb"}, + {file = "multidict-5.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:0ffdb4b897b15df798c0a5939a0323ccf703f2bae551dfab4eb1af7fbab38ead"}, + {file = "multidict-5.0.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:4ef76ce695da72e176f6a51867afb3bf300ce16ba2597824caaef625af5906a9"}, + {file = "multidict-5.0.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:711289412b78cf41a21457f4c806890466013d62bf4296bd3d71fad73ff8a581"}, + {file = "multidict-5.0.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:2b0cfc33f53e5c8226f7d7c4e126fa0780f970ef1e96f7c6353da7d01eafe490"}, + {file = "multidict-5.0.0-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:28b5913e5b6fef273e5d4230b61f33c8a51c3ce5f44a88582dee6b5ca5c9977b"}, + {file = "multidict-5.0.0-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:a5eca9ee72b372199c2b76672145e47d3c829889eefa2037b1f3018f54e5f67d"}, + {file = "multidict-5.0.0-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:20eaf1c279c543e07c164e4ac02151488829177da06607efa7ccfecd71b21e79"}, + {file = "multidict-5.0.0-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:ec8bc0ab00c76c4260a201eaa58812ea8b1b7fde0ecf5f9c9365a182bd4691ed"}, + {file = "multidict-5.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:aad240c1429e386af38a2d6761032f0bec5177fed7c5f582c835c99fff135b5c"}, + {file = "multidict-5.0.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:52b5b51281d760197ce3db063c166fdb626e01c8e428a325aa37198ce31c9565"}, + {file = "multidict-5.0.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:5263359a03368985b5296b7a73363d761a269848081879ba04a6e4bfd0cf4a78"}, + {file = "multidict-5.0.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:620c39b1270b68e194023ad471b6a54bdb517bb48515939c9829b56c783504a3"}, + {file = "multidict-5.0.0-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:2739d1d9237835122b27d88990849ecf41ef670e0fcb876159edd236ca9ef40f"}, + {file = "multidict-5.0.0-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:62f6e66931fb87e9016e7c1cc806ab4f3e39392fd502362df3cac888078b27cb"}, + {file = "multidict-5.0.0-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:5dd303b545b62f9d2b14f99fbdb84c109a20e64a57f6a192fe6aebcb6263b59d"}, + {file = "multidict-5.0.0-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:60b12d14bc122ba2dae1e4460a891b3a96e73d815b4365675f6ec0a1725416a5"}, + {file = "multidict-5.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:79dc3e6e7ce853fb7ed17c134e01fcb0d0c826b33201aa2a910fb27ed75c2eb9"}, + {file = "multidict-5.0.0.tar.gz", hash = "sha256:1b324444299c3a49b601b1bf621fc21704e29066f6ac2b7d7e4034a4a18662a1"}, ] mypy = [ {file = "mypy-0.740-cp35-cp35m-macosx_10_6_x86_64.whl", hash = "sha256:9371290aa2cad5ad133e4cdc43892778efd13293406f7340b9ffe99d5ec7c1d9"}, @@ -3180,44 +3202,46 @@ petl = [ {file = "petl-1.6.7.tar.gz", hash = "sha256:5185712705f7be4757276a98757cc8d749045c4576ca80c1da2a27d3fba33863"}, ] phonenumberslite = [ - {file = "phonenumberslite-8.12.10-py2.py3-none-any.whl", hash = "sha256:976e1ba78c04a2e121556ca18b3379ed89025136c9739e549185d8098116ef6f"}, - {file = "phonenumberslite-8.12.10.tar.gz", hash = "sha256:7d28a92dc1bc0418a64d3d73b8897b6e9a43541b718d4320b08406309cd96a46"}, + {file = "phonenumberslite-8.12.11-py2.py3-none-any.whl", hash = "sha256:e92b8f82ee6248ebd13248762b6b1d136dcb574c9c6f90d60745833412f3bd18"}, + {file = "phonenumberslite-8.12.11.tar.gz", hash = "sha256:aa63b5910ab2a1cd9cd5c22ca6439972e80f2e1bdf2638b98f610469cd572aa9"}, ] pillow = [ - {file = "Pillow-7.2.0-cp35-cp35m-macosx_10_10_intel.whl", hash = "sha256:1ca594126d3c4def54babee699c055a913efb01e106c309fa6b04405d474d5ae"}, - {file = "Pillow-7.2.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c92302a33138409e8f1ad16731568c55c9053eee71bb05b6b744067e1b62380f"}, - {file = "Pillow-7.2.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:8dad18b69f710bf3a001d2bf3afab7c432785d94fcf819c16b5207b1cfd17d38"}, - {file = "Pillow-7.2.0-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:431b15cffbf949e89df2f7b48528be18b78bfa5177cb3036284a5508159492b5"}, - {file = "Pillow-7.2.0-cp35-cp35m-win32.whl", hash = "sha256:09d7f9e64289cb40c2c8d7ad674b2ed6105f55dc3b09aa8e4918e20a0311e7ad"}, - {file = "Pillow-7.2.0-cp35-cp35m-win_amd64.whl", hash = "sha256:0295442429645fa16d05bd567ef5cff178482439c9aad0411d3f0ce9b88b3a6f"}, - {file = "Pillow-7.2.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:ec29604081f10f16a7aea809ad42e27764188fc258b02259a03a8ff7ded3808d"}, - {file = "Pillow-7.2.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:612cfda94e9c8346f239bf1a4b082fdd5c8143cf82d685ba2dba76e7adeeb233"}, - {file = "Pillow-7.2.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0a80dd307a5d8440b0a08bd7b81617e04d870e40a3e46a32d9c246e54705e86f"}, - {file = "Pillow-7.2.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:06aba4169e78c439d528fdeb34762c3b61a70813527a2c57f0540541e9f433a8"}, - {file = "Pillow-7.2.0-cp36-cp36m-win32.whl", hash = "sha256:f7e30c27477dffc3e85c2463b3e649f751789e0f6c8456099eea7ddd53be4a8a"}, - {file = "Pillow-7.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:ffe538682dc19cc542ae7c3e504fdf54ca7f86fb8a135e59dd6bc8627eae6cce"}, - {file = "Pillow-7.2.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:94cf49723928eb6070a892cb39d6c156f7b5a2db4e8971cb958f7b6b104fb4c4"}, - {file = "Pillow-7.2.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6edb5446f44d901e8683ffb25ebdfc26988ee813da3bf91e12252b57ac163727"}, - {file = "Pillow-7.2.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:52125833b070791fcb5710fabc640fc1df07d087fc0c0f02d3661f76c23c5b8b"}, - {file = "Pillow-7.2.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:9ad7f865eebde135d526bb3163d0b23ffff365cf87e767c649550964ad72785d"}, - {file = "Pillow-7.2.0-cp37-cp37m-win32.whl", hash = "sha256:c79f9c5fb846285f943aafeafda3358992d64f0ef58566e23484132ecd8d7d63"}, - {file = "Pillow-7.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d350f0f2c2421e65fbc62690f26b59b0bcda1b614beb318c81e38647e0f673a1"}, - {file = "Pillow-7.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:6d7741e65835716ceea0fd13a7d0192961212fd59e741a46bbed7a473c634ed6"}, - {file = "Pillow-7.2.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:edf31f1150778abd4322444c393ab9c7bd2af271dd4dafb4208fb613b1f3cdc9"}, - {file = "Pillow-7.2.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:d08b23fdb388c0715990cbc06866db554e1822c4bdcf6d4166cf30ac82df8c41"}, - {file = "Pillow-7.2.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:5e51ee2b8114def244384eda1c82b10e307ad9778dac5c83fb0943775a653cd8"}, - {file = "Pillow-7.2.0-cp38-cp38-win32.whl", hash = "sha256:725aa6cfc66ce2857d585f06e9519a1cc0ef6d13f186ff3447ab6dff0a09bc7f"}, - {file = "Pillow-7.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:a060cf8aa332052df2158e5a119303965be92c3da6f2d93b6878f0ebca80b2f6"}, - {file = "Pillow-7.2.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:25930fadde8019f374400f7986e8404c8b781ce519da27792cbe46eabec00c4d"}, - {file = "Pillow-7.2.0.tar.gz", hash = "sha256:97f9e7953a77d5a70f49b9a48da7776dc51e9b738151b22dacf101641594a626"}, + {file = "Pillow-8.0.1-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:b63d4ff734263ae4ce6593798bcfee6dbfb00523c82753a3a03cbc05555a9cc3"}, + {file = "Pillow-8.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5f9403af9c790cc18411ea398a6950ee2def2a830ad0cfe6dc9122e6d528b302"}, + {file = "Pillow-8.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:6b4a8fd632b4ebee28282a9fef4c341835a1aa8671e2770b6f89adc8e8c2703c"}, + {file = "Pillow-8.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:cc3ea6b23954da84dbee8025c616040d9aa5eaf34ea6895a0a762ee9d3e12e11"}, + {file = "Pillow-8.0.1-cp36-cp36m-win32.whl", hash = "sha256:d8a96747df78cda35980905bf26e72960cba6d355ace4780d4bdde3b217cdf1e"}, + {file = "Pillow-8.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:7ba0ba61252ab23052e642abdb17fd08fdcfdbbf3b74c969a30c58ac1ade7cd3"}, + {file = "Pillow-8.0.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:795e91a60f291e75de2e20e6bdd67770f793c8605b553cb6e4387ce0cb302e09"}, + {file = "Pillow-8.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0a2e8d03787ec7ad71dc18aec9367c946ef8ef50e1e78c71f743bc3a770f9fae"}, + {file = "Pillow-8.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:006de60d7580d81f4a1a7e9f0173dc90a932e3905cc4d47ea909bc946302311a"}, + {file = "Pillow-8.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:bd7bf289e05470b1bc74889d1466d9ad4a56d201f24397557b6f65c24a6844b8"}, + {file = "Pillow-8.0.1-cp37-cp37m-win32.whl", hash = "sha256:95edb1ed513e68bddc2aee3de66ceaf743590bf16c023fb9977adc4be15bd3f0"}, + {file = "Pillow-8.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:e38d58d9138ef972fceb7aeec4be02e3f01d383723965bfcef14d174c8ccd039"}, + {file = "Pillow-8.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:d3d07c86d4efa1facdf32aa878bd508c0dc4f87c48125cc16b937baa4e5b5e11"}, + {file = "Pillow-8.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:fbd922f702582cb0d71ef94442bfca57624352622d75e3be7a1e7e9360b07e72"}, + {file = "Pillow-8.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:92c882b70a40c79de9f5294dc99390671e07fc0b0113d472cbea3fde15db1792"}, + {file = "Pillow-8.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7c9401e68730d6c4245b8e361d3d13e1035cbc94db86b49dc7da8bec235d0015"}, + {file = "Pillow-8.0.1-cp38-cp38-win32.whl", hash = "sha256:6c1aca8231625115104a06e4389fcd9ec88f0c9befbabd80dc206c35561be271"}, + {file = "Pillow-8.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:cc9ec588c6ef3a1325fa032ec14d97b7309db493782ea8c304666fb10c3bd9a7"}, + {file = "Pillow-8.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:eb472586374dc66b31e36e14720747595c2b265ae962987261f044e5cce644b5"}, + {file = "Pillow-8.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:0eeeae397e5a79dc088d8297a4c2c6f901f8fb30db47795113a4a605d0f1e5ce"}, + {file = "Pillow-8.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:81f812d8f5e8a09b246515fac141e9d10113229bc33ea073fec11403b016bcf3"}, + {file = "Pillow-8.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:895d54c0ddc78a478c80f9c438579ac15f3e27bf442c2a9aa74d41d0e4d12544"}, + {file = "Pillow-8.0.1-cp39-cp39-win32.whl", hash = "sha256:2fb113757a369a6cdb189f8df3226e995acfed0a8919a72416626af1a0a71140"}, + {file = "Pillow-8.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:59e903ca800c8cfd1ebe482349ec7c35687b95e98cefae213e271c8c7fffa021"}, + {file = "Pillow-8.0.1-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:5abd653a23c35d980b332bc0431d39663b1709d64142e3652890df4c9b6970f6"}, + {file = "Pillow-8.0.1-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:4b0ef2470c4979e345e4e0cc1bbac65fda11d0d7b789dbac035e4c6ce3f98adb"}, + {file = "Pillow-8.0.1-pp37-pypy37_pp73-win32.whl", hash = "sha256:8de332053707c80963b589b22f8e0229f1be1f3ca862a932c1bcd48dafb18dd8"}, + {file = "Pillow-8.0.1.tar.gz", hash = "sha256:11c5c6e9b02c9dac08af04f093eb5a2f84857df70a7d4a6a6ad461aca803fb9e"}, ] pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] pre-commit = [ - {file = "pre_commit-2.7.1-py2.py3-none-any.whl", hash = "sha256:810aef2a2ba4f31eed1941fc270e72696a1ad5590b9751839c90807d0fff6b9a"}, - {file = "pre_commit-2.7.1.tar.gz", hash = "sha256:c54fd3e574565fe128ecc5e7d2f91279772ddb03f8729645fa812fe809084a70"}, + {file = "pre_commit-2.8.1-py2.py3-none-any.whl", hash = "sha256:7eadaa7f4547a8a19b83230ce430ba81bbe4797bd41c8d7fb54b246164628d1f"}, + {file = "pre_commit-2.8.1.tar.gz", hash = "sha256:8fb2037c404ef8c87125e72564f316cf2bc94fc9c1cb184b8352117de747e164"}, ] prices = [ {file = "prices-1.1.0-py2.py3-none-any.whl", hash = "sha256:4086cf0d895112317da51256901d81a68061434acb240aebf9146fa04fef4554"}, @@ -3227,11 +3251,11 @@ promise = [ {file = "promise-2.3.tar.gz", hash = "sha256:dfd18337c523ba4b6a58801c164c1904a9d4d1b1747c7d5dbf45b693a49d93d0"}, ] prompt-toolkit = [ - {file = "prompt_toolkit-3.0.7-py3-none-any.whl", hash = "sha256:83074ee28ad4ba6af190593d4d4c607ff525272a504eb159199b6dd9f950c950"}, - {file = "prompt_toolkit-3.0.7.tar.gz", hash = "sha256:822f4605f28f7d2ba6b0b09a31e25e140871e96364d1d377667b547bb3bf4489"}, + {file = "prompt_toolkit-3.0.8-py3-none-any.whl", hash = "sha256:7debb9a521e0b1ee7d2fe96ee4bd60ef03c6492784de0547337ca4433e46aa63"}, + {file = "prompt_toolkit-3.0.8.tar.gz", hash = "sha256:25c95d2ac813909f813c93fde734b6e44406d1477a9faef7c915ff37d39c0a8c"}, ] proto-plus = [ - {file = "proto-plus-1.9.1.tar.gz", hash = "sha256:2028b1466bff50cda055bdaaa069511e119d933e3c2af21b4002a1d13ff4ac68"}, + {file = "proto-plus-1.11.0.tar.gz", hash = "sha256:416a0f13987789333cd8760a0ee998f8eccd6d7165ee9f283d64ca2de3e8774d"}, ] protobuf = [ {file = "protobuf-3.13.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9c2e63c1743cba12737169c447374fab3dfeb18111a460a8c1a000e35836b18c"}, @@ -3369,8 +3393,8 @@ pyphen = [ {file = "Pyphen-0.9.5.tar.gz", hash = "sha256:3b633a50873156d777e1f1075ba4d8e96a6ad0a3ca42aa3ea9a6259f93f18921"}, ] pytest = [ - {file = "pytest-6.1.1-py3-none-any.whl", hash = "sha256:7a8190790c17d79a11f847fba0b004ee9a8122582ebff4729a082c109e81a4c9"}, - {file = "pytest-6.1.1.tar.gz", hash = "sha256:8f593023c1a0f916110285b6efd7f99db07d59546e3d8c36fc60e2ab05d3be92"}, + {file = "pytest-6.1.2-py3-none-any.whl", hash = "sha256:4288fed0d9153d9646bfcdf0c0428197dba1ecb27a33bb6e031d002fa88653fe"}, + {file = "pytest-6.1.2.tar.gz", hash = "sha256:c0a7e94a8cdbc5422a51ccdad8e6f1024795939cc89159a0ae7f0b316ad3823e"}, ] pytest-celery = [ {file = "pytest-celery-0.0.0a1.tar.gz", hash = "sha256:3e0e0817c2d3f2870dafebd915bf13100fc12920b5d42dfe5fdc35844fe42e62"}, @@ -3407,8 +3431,12 @@ python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, ] +python-dotenv = [ + {file = "python-dotenv-0.15.0.tar.gz", hash = "sha256:587825ed60b1711daea4832cf37524dfd404325b7db5e25ebe88c495c9f807a0"}, + {file = "python_dotenv-0.15.0-py2.py3-none-any.whl", hash = "sha256:0c8d1b80d1a1e91717ea7d526178e3882732420b03f08afea0406db6402e220e"}, +] python-json-logger = [ - {file = "python-json-logger-2.0.0.tar.gz", hash = "sha256:6c15023a8571200228472d4c9de7cb891cd45f670061f7729b8209bf643d5bbf"}, + {file = "python-json-logger-2.0.1.tar.gz", hash = "sha256:f26eea7898db40609563bed0a7ca11af12e2a79858632706d835a0f961b7d398"}, ] python-magic = [ {file = "python-magic-0.4.18.tar.gz", hash = "sha256:b757db2a5289ea3f1ced9e60f072965243ea43a2221430048fd8cacab17be0ce"}, @@ -3455,27 +3483,33 @@ redis = [ {file = "redis-3.5.3.tar.gz", hash = "sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2"}, ] regex = [ - {file = "regex-2020.7.14-cp27-cp27m-win32.whl", hash = "sha256:e46d13f38cfcbb79bfdb2964b0fe12561fe633caf964a77a5f8d4e45fe5d2ef7"}, - {file = "regex-2020.7.14-cp27-cp27m-win_amd64.whl", hash = "sha256:6961548bba529cac7c07af2fd4d527c5b91bb8fe18995fed6044ac22b3d14644"}, - {file = "regex-2020.7.14-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c50a724d136ec10d920661f1442e4a8b010a4fe5aebd65e0c2241ea41dbe93dc"}, - {file = "regex-2020.7.14-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8a51f2c6d1f884e98846a0a9021ff6861bdb98457879f412fdc2b42d14494067"}, - {file = "regex-2020.7.14-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:9c568495e35599625f7b999774e29e8d6b01a6fb684d77dee1f56d41b11b40cd"}, - {file = "regex-2020.7.14-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:51178c738d559a2d1071ce0b0f56e57eb315bcf8f7d4cf127674b533e3101f88"}, - {file = "regex-2020.7.14-cp36-cp36m-win32.whl", hash = "sha256:9eddaafb3c48e0900690c1727fba226c4804b8e6127ea409689c3bb492d06de4"}, - {file = "regex-2020.7.14-cp36-cp36m-win_amd64.whl", hash = "sha256:14a53646369157baa0499513f96091eb70382eb50b2c82393d17d7ec81b7b85f"}, - {file = "regex-2020.7.14-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:1269fef3167bb52631ad4fa7dd27bf635d5a0790b8e6222065d42e91bede4162"}, - {file = "regex-2020.7.14-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d0a5095d52b90ff38592bbdc2644f17c6d495762edf47d876049cfd2968fbccf"}, - {file = "regex-2020.7.14-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:4c037fd14c5f4e308b8370b447b469ca10e69427966527edcab07f52d88388f7"}, - {file = "regex-2020.7.14-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:bc3d98f621898b4a9bc7fecc00513eec8f40b5b83913d74ccb445f037d58cd89"}, - {file = "regex-2020.7.14-cp37-cp37m-win32.whl", hash = "sha256:46bac5ca10fb748d6c55843a931855e2727a7a22584f302dd9bb1506e69f83f6"}, - {file = "regex-2020.7.14-cp37-cp37m-win_amd64.whl", hash = "sha256:0dc64ee3f33cd7899f79a8d788abfbec168410be356ed9bd30bbd3f0a23a7204"}, - {file = "regex-2020.7.14-cp38-cp38-manylinux1_i686.whl", hash = "sha256:5ea81ea3dbd6767873c611687141ec7b06ed8bab43f68fad5b7be184a920dc99"}, - {file = "regex-2020.7.14-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:bbb332d45b32df41200380fff14712cb6093b61bd142272a10b16778c418e98e"}, - {file = "regex-2020.7.14-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:c11d6033115dc4887c456565303f540c44197f4fc1a2bfb192224a301534888e"}, - {file = "regex-2020.7.14-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:75aaa27aa521a182824d89e5ab0a1d16ca207318a6b65042b046053cfc8ed07a"}, - {file = "regex-2020.7.14-cp38-cp38-win32.whl", hash = "sha256:d6cff2276e502b86a25fd10c2a96973fdb45c7a977dca2138d661417f3728341"}, - {file = "regex-2020.7.14-cp38-cp38-win_amd64.whl", hash = "sha256:7a2dd66d2d4df34fa82c9dc85657c5e019b87932019947faece7983f2089a840"}, - {file = "regex-2020.7.14.tar.gz", hash = "sha256:3a3af27a8d23143c49a3420efe5b3f8cf1a48c6fc8bc6856b03f638abc1833bb"}, + {file = "regex-2020.10.28-cp27-cp27m-win32.whl", hash = "sha256:4b5a9bcb56cc146c3932c648603b24514447eafa6ce9295234767bf92f69b504"}, + {file = "regex-2020.10.28-cp27-cp27m-win_amd64.whl", hash = "sha256:c13d311a4c4a8d671f5860317eb5f09591fbe8259676b86a85769423b544451e"}, + {file = "regex-2020.10.28-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c8a2b7ccff330ae4c460aff36626f911f918555660cc28163417cb84ffb25789"}, + {file = "regex-2020.10.28-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4afa350f162551cf402bfa3cd8302165c8e03e689c897d185f16a167328cc6dd"}, + {file = "regex-2020.10.28-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:b88fa3b8a3469f22b4f13d045d9bd3eda797aa4e406fde0a2644bc92bbdd4bdd"}, + {file = "regex-2020.10.28-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:f43109822df2d3faac7aad79613f5f02e4eab0fc8ad7932d2e70e2a83bd49c26"}, + {file = "regex-2020.10.28-cp36-cp36m-win32.whl", hash = "sha256:8092a5a06ad9a7a247f2a76ace121183dc4e1a84c259cf9c2ce3bbb69fac3582"}, + {file = "regex-2020.10.28-cp36-cp36m-win_amd64.whl", hash = "sha256:49461446b783945597c4076aea3f49aee4b4ce922bd241e4fcf62a3e7c61794c"}, + {file = "regex-2020.10.28-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:8ca9dca965bd86ea3631b975d63b0693566d3cc347e55786d5514988b6f5b84c"}, + {file = "regex-2020.10.28-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ea37320877d56a7f0a1e6a625d892cf963aa7f570013499f5b8d5ab8402b5625"}, + {file = "regex-2020.10.28-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:3a5f08039eee9ea195a89e180c5762bfb55258bfb9abb61a20d3abee3b37fd12"}, + {file = "regex-2020.10.28-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:cb905f3d2e290a8b8f1579d3984f2cfa7c3a29cc7cba608540ceeed18513f520"}, + {file = "regex-2020.10.28-cp37-cp37m-win32.whl", hash = "sha256:a62162be05edf64f819925ea88d09d18b09bebf20971b363ce0c24e8b4aa14c0"}, + {file = "regex-2020.10.28-cp37-cp37m-win_amd64.whl", hash = "sha256:03855ee22980c3e4863dc84c42d6d2901133362db5daf4c36b710dd895d78f0a"}, + {file = "regex-2020.10.28-cp38-cp38-manylinux1_i686.whl", hash = "sha256:625116aca6c4b57c56ea3d70369cacc4d62fead4930f8329d242e4fe7a58ce4b"}, + {file = "regex-2020.10.28-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2dc522e25e57e88b4980d2bdd334825dbf6fa55f28a922fc3bfa60cc09e5ef53"}, + {file = "regex-2020.10.28-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:119e0355dbdd4cf593b17f2fc5dbd4aec2b8899d0057e4957ba92f941f704bf5"}, + {file = "regex-2020.10.28-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:cfcf28ed4ce9ced47b9b9670a4f0d3d3c0e4d4779ad4dadb1ad468b097f808aa"}, + {file = "regex-2020.10.28-cp38-cp38-win32.whl", hash = "sha256:06b52815d4ad38d6524666e0d50fe9173533c9cc145a5779b89733284e6f688f"}, + {file = "regex-2020.10.28-cp38-cp38-win_amd64.whl", hash = "sha256:c3466a84fce42c2016113101018a9981804097bacbab029c2d5b4fcb224b89de"}, + {file = "regex-2020.10.28-cp39-cp39-manylinux1_i686.whl", hash = "sha256:c2c6c56ee97485a127555c9595c069201b5161de9d05495fbe2132b5ac104786"}, + {file = "regex-2020.10.28-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:1ec66700a10e3c75f1f92cbde36cca0d3aaee4c73dfa26699495a3a30b09093c"}, + {file = "regex-2020.10.28-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:11116d424734fe356d8777f89d625f0df783251ada95d6261b4c36ad27a394bb"}, + {file = "regex-2020.10.28-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f1fce1e4929157b2afeb4bb7069204d4370bab9f4fc03ca1fbec8bd601f8c87d"}, + {file = "regex-2020.10.28-cp39-cp39-win32.whl", hash = "sha256:832339223b9ce56b7b15168e691ae654d345ac1635eeb367ade9ecfe0e66bee0"}, + {file = "regex-2020.10.28-cp39-cp39-win_amd64.whl", hash = "sha256:654c1635f2313d0843028487db2191530bca45af61ca85d0b16555c399625b0e"}, + {file = "regex-2020.10.28.tar.gz", hash = "sha256:dd3e6547ecf842a29cf25123fbf8d2461c53c8d37aa20d87ecee130c89b7079b"}, ] requests = [ {file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"}, @@ -3494,8 +3528,8 @@ s3transfer = [ {file = "s3transfer-0.3.3.tar.gz", hash = "sha256:921a37e2aefc64145e7b73d50c71bb4f26f46e4c9f414dc648c6245ff92cf7db"}, ] sentry-sdk = [ - {file = "sentry-sdk-0.17.3.tar.gz", hash = "sha256:0af429c221670e602f960fca85ca3f607c85510a91f11e8be8f742a978127f78"}, - {file = "sentry_sdk-0.17.3-py2.py3-none-any.whl", hash = "sha256:a088a1054673c6a19ea590045c871c38da029ef743b61a07bfee95e9f3c060f7"}, + {file = "sentry-sdk-0.19.1.tar.gz", hash = "sha256:5cf36eb6b1dc62d55f3c64289792cbaebc8ffa5a9da14474f49b46d20caa7fc8"}, + {file = "sentry_sdk-0.19.1-py2.py3-none-any.whl", hash = "sha256:0eea248408d36e8e7037c7b73827bea20b13a4375bf1719c406cae6fcbc094e3"}, ] singledispatch = [ {file = "singledispatch-3.4.0.3-py2.py3-none-any.whl", hash = "sha256:833b46966687b3de7f438c761ac475213e53b306740f1abfaa86e1d1aae56aa8"}, @@ -3518,12 +3552,12 @@ soupsieve = [ {file = "soupsieve-2.0.1.tar.gz", hash = "sha256:a59dc181727e95d25f781f0eb4fd1825ff45590ec8ff49eadfd7f1a537cc0232"}, ] sqlparse = [ - {file = "sqlparse-0.3.1-py2.py3-none-any.whl", hash = "sha256:022fb9c87b524d1f7862b3037e541f68597a730a8843245c349fc93e1643dc4e"}, - {file = "sqlparse-0.3.1.tar.gz", hash = "sha256:e162203737712307dfe78860cc56c8da8a852ab2ee33750e33aeadf38d12c548"}, + {file = "sqlparse-0.4.1-py3-none-any.whl", hash = "sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0"}, + {file = "sqlparse-0.4.1.tar.gz", hash = "sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8"}, ] stripe = [ - {file = "stripe-2.54.0-py2.py3-none-any.whl", hash = "sha256:6daf0dcb7f9cb8d1af93e94eb7d91df4c0b112db517c8c446017ea0b7f037c83"}, - {file = "stripe-2.54.0.tar.gz", hash = "sha256:a622bce0d6d0ac99a53b6e6a6475c39250207d644f28ad0ed276af7b96d12617"}, + {file = "stripe-2.55.0-py2.py3-none-any.whl", hash = "sha256:833313d28dcceca71128ee915c2dacbbf235c909e0a01b0f94ee5037e1c46109"}, + {file = "stripe-2.55.0.tar.gz", hash = "sha256:2eebf023595e8aa9d65d8b46ccc3c716185bb9625d0e39d3956282fd7525848d"}, ] sympy = [ {file = "sympy-1.6.2-py3-none-any.whl", hash = "sha256:0f6c5724a999eca02f4b453260b0c7151d6fa076313f441274db98bbf97ba8cd"}, @@ -3560,15 +3594,15 @@ tornado = [ {file = "tornado-6.0.4.tar.gz", hash = "sha256:0fe2d45ba43b00a41cd73f8be321a44936dc1aba233dee979f17a042b83eb6dc"}, ] tox = [ - {file = "tox-3.20.0-py2.py3-none-any.whl", hash = "sha256:e6318f404aff16522ff5211c88cab82b39af121735a443674e4e2e65f4e4637b"}, - {file = "tox-3.20.0.tar.gz", hash = "sha256:eb629ddc60e8542fd4a1956b2462e3b8771d49f1ff630cecceacaa0fbfb7605a"}, + {file = "tox-3.20.1-py2.py3-none-any.whl", hash = "sha256:42ce19ce5dc2f6d6b1fdc5666c476e1f1e2897359b47e0aa3a5b774f335d57c2"}, + {file = "tox-3.20.1.tar.gz", hash = "sha256:4321052bfe28f9d85082341ca8e233e3ea901fdd14dab8a5d3fbd810269fbaf6"}, ] tqdm = [ - {file = "tqdm-4.50.0-py2.py3-none-any.whl", hash = "sha256:2dd75fdb764f673b8187643496fcfbeac38348015b665878e582b152f3391cdb"}, - {file = "tqdm-4.50.0.tar.gz", hash = "sha256:93b7a6a9129fce904f6df4cf3ae7ff431d779be681a95c3344c26f3e6c09abfa"}, + {file = "tqdm-4.51.0-py2.py3-none-any.whl", hash = "sha256:9ad44aaf0fc3697c06f6e05c7cf025dd66bc7bcb7613c66d85f4464c47ac8fad"}, + {file = "tqdm-4.51.0.tar.gz", hash = "sha256:ef54779f1c09f346b2b5a8e5c61f96fbcb639929e640e59f8cf810794f406432"}, ] transifex-client = [ - {file = "transifex-client-0.13.12.tar.gz", hash = "sha256:f52c07f5810361c59114492177325868acbc354357fc1e8f3c9afed0b05f5e6d"}, + {file = "transifex-client-0.14.1.tar.gz", hash = "sha256:a8a06330acb97403b24153fb51c2c6ae5c8ab0a989fed06f8a27ce70323c7d5e"}, ] typed-ast = [ {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, @@ -3608,12 +3642,12 @@ unidecode = [ {file = "Unidecode-1.1.1.tar.gz", hash = "sha256:2b6aab710c2a1647e928e36d69c21e76b453cd455f4e2621000e54b2a9b8cce8"}, ] urllib3 = [ - {file = "urllib3-1.25.10-py2.py3-none-any.whl", hash = "sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461"}, - {file = "urllib3-1.25.10.tar.gz", hash = "sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a"}, + {file = "urllib3-1.25.11-py2.py3-none-any.whl", hash = "sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e"}, + {file = "urllib3-1.25.11.tar.gz", hash = "sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2"}, ] uvicorn = [ - {file = "uvicorn-0.11.8-py3-none-any.whl", hash = "sha256:4b70ddb4c1946e39db9f3082d53e323dfd50634b95fd83625d778729ef1730ef"}, - {file = "uvicorn-0.11.8.tar.gz", hash = "sha256:46a83e371f37ea7ff29577d00015f02c942410288fb57def6440f2653fff1d26"}, + {file = "uvicorn-0.12.2-py3-none-any.whl", hash = "sha256:e5dbed4a8a44c7b04376021021d63798d6a7bcfae9c654a0b153577b93854fba"}, + {file = "uvicorn-0.12.2.tar.gz", hash = "sha256:8ff7495c74b8286a341526ff9efa3988ebab9a4b2f561c7438c3cb420992d7dd"}, ] uvloop = [ {file = "uvloop-0.14.0-cp35-cp35m-macosx_10_11_x86_64.whl", hash = "sha256:08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd"}, @@ -3627,16 +3661,20 @@ uvloop = [ {file = "uvloop-0.14.0.tar.gz", hash = "sha256:123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e"}, ] vcrpy = [ - {file = "vcrpy-4.1.0-py2.py3-none-any.whl", hash = "sha256:d833248442bbc560599add895c9ab0ef518676579e8dc72d8b0933bdb3880253"}, - {file = "vcrpy-4.1.0.tar.gz", hash = "sha256:4138e79eb35981ad391406cbb7227bce7eba8bad788dcf1a89c2e4a8b740debe"}, + {file = "vcrpy-4.1.1-py2.py3-none-any.whl", hash = "sha256:12c3fcdae7b88ecf11fc0d3e6d77586549d4575a2ceee18e82eee75c1f626162"}, + {file = "vcrpy-4.1.1.tar.gz", hash = "sha256:57095bf22fc0a2d99ee9674cdafebed0f3ba763018582450706f7d3a74fff599"}, ] vine = [ {file = "vine-5.0.0-py2.py3-none-any.whl", hash = "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30"}, {file = "vine-5.0.0.tar.gz", hash = "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e"}, ] virtualenv = [ - {file = "virtualenv-20.0.31-py2.py3-none-any.whl", hash = "sha256:e0305af10299a7fb0d69393d8f04cb2965dda9351140d11ac8db4e5e3970451b"}, - {file = "virtualenv-20.0.31.tar.gz", hash = "sha256:43add625c53c596d38f971a465553f6318decc39d98512bc100fa1b1e839c8dc"}, + {file = "virtualenv-20.1.0-py2.py3-none-any.whl", hash = "sha256:b0011228208944ce71052987437d3843e05690b2f23d1c7da4263fde104c97a2"}, + {file = "virtualenv-20.1.0.tar.gz", hash = "sha256:b8d6110f493af256a40d65e29846c69340a947669eec8ce784fcf3dd3af28380"}, +] +watchgod = [ + {file = "watchgod-0.6-py35.py36.py37-none-any.whl", hash = "sha256:59700dab7445aa8e6067a5b94f37bae90fc367554549b1ed2e9d0f4f38a90d2a"}, + {file = "watchgod-0.6.tar.gz", hash = "sha256:e9cca0ab9c63f17fc85df9fd8bd18156ff00aff04ebe5976cee473f4968c6858"}, ] wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, @@ -3678,21 +3716,37 @@ wrapt = [ {file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"}, ] yarl = [ - {file = "yarl-1.5.1-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:db6db0f45d2c63ddb1a9d18d1b9b22f308e52c83638c26b422d520a815c4b3fb"}, - {file = "yarl-1.5.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:17668ec6722b1b7a3a05cc0167659f6c95b436d25a36c2d52db0eca7d3f72593"}, - {file = "yarl-1.5.1-cp35-cp35m-win32.whl", hash = "sha256:040b237f58ff7d800e6e0fd89c8439b841f777dd99b4a9cca04d6935564b9409"}, - {file = "yarl-1.5.1-cp35-cp35m-win_amd64.whl", hash = "sha256:f18d68f2be6bf0e89f1521af2b1bb46e66ab0018faafa81d70f358153170a317"}, - {file = "yarl-1.5.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:c52ce2883dc193824989a9b97a76ca86ecd1fa7955b14f87bf367a61b6232511"}, - {file = "yarl-1.5.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ce584af5de8830d8701b8979b18fcf450cef9a382b1a3c8ef189bedc408faf1e"}, - {file = "yarl-1.5.1-cp36-cp36m-win32.whl", hash = "sha256:df89642981b94e7db5596818499c4b2219028f2a528c9c37cc1de45bf2fd3a3f"}, - {file = "yarl-1.5.1-cp36-cp36m-win_amd64.whl", hash = "sha256:3a584b28086bc93c888a6c2aa5c92ed1ae20932f078c46509a66dce9ea5533f2"}, - {file = "yarl-1.5.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:da456eeec17fa8aa4594d9a9f27c0b1060b6a75f2419fe0c00609587b2695f4a"}, - {file = "yarl-1.5.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bc2f976c0e918659f723401c4f834deb8a8e7798a71be4382e024bcc3f7e23a8"}, - {file = "yarl-1.5.1-cp37-cp37m-win32.whl", hash = "sha256:4439be27e4eee76c7632c2427ca5e73703151b22cae23e64adb243a9c2f565d8"}, - {file = "yarl-1.5.1-cp37-cp37m-win_amd64.whl", hash = "sha256:48e918b05850fffb070a496d2b5f97fc31d15d94ca33d3d08a4f86e26d4e7c5d"}, - {file = "yarl-1.5.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:9b930776c0ae0c691776f4d2891ebc5362af86f152dd0da463a6614074cb1b02"}, - {file = "yarl-1.5.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:b3b9ad80f8b68519cc3372a6ca85ae02cc5a8807723ac366b53c0f089db19e4a"}, - {file = "yarl-1.5.1-cp38-cp38-win32.whl", hash = "sha256:f379b7f83f23fe12823085cd6b906edc49df969eb99757f58ff382349a3303c6"}, - {file = "yarl-1.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:9102b59e8337f9874638fcfc9ac3734a0cfadb100e47d55c20d0dc6087fb4692"}, - {file = "yarl-1.5.1.tar.gz", hash = "sha256:c22c75b5f394f3d47105045ea551e08a3e804dc7e01b37800ca35b58f856c3d6"}, + {file = "yarl-1.6.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:d77f6c9133d2aabb290a7846aaa74ec14d7b5ab35b01591fac5a70c4a8c959a2"}, + {file = "yarl-1.6.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:311effab3b3828ab34f0e661bb57ff422f67d5c33056298bda4c12195251f8dd"}, + {file = "yarl-1.6.2-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:f835015a825980b65356e9520979a1564c56efea7da7d4b68a14d4a07a3a7336"}, + {file = "yarl-1.6.2-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:59f78b5da34ddcffb663b772f7619e296518712e022e57fc5d9f921818e2ab7c"}, + {file = "yarl-1.6.2-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:3526cb5905907f0e42bee7ef57ae4a5f02bc27dcac27859269e2bba0caa4c2b6"}, + {file = "yarl-1.6.2-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:e77bf79ad1ccae672eab22453838382fe9029fc27c8029e84913855512a587d8"}, + {file = "yarl-1.6.2-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:b3dd1052afd436ba737e61f5d3bed1f43a7f9a33fc58fbe4226eb919a7006019"}, + {file = "yarl-1.6.2-cp36-cp36m-win_amd64.whl", hash = "sha256:6f29115b0c330da25a04f48612d75333bca04521181a666ca0b8761005a99150"}, + {file = "yarl-1.6.2-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f3031c78edf10315abe232254e6a36b65afe65fded41ee54ed7976d0b2cdf0da"}, + {file = "yarl-1.6.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4bed5cd7c8e69551eb19df15295ba90e62b9a6a1149c76eb4a9bab194402a156"}, + {file = "yarl-1.6.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:39b1e586f34b1d2512c9b39aa3cf24c870c972d525e36edc9ee19065db4737bb"}, + {file = "yarl-1.6.2-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:03b7a44384ad60be1b7be93c2a24dc74895f8d767ea0bce15b2f6fc7695a3843"}, + {file = "yarl-1.6.2-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:a1fd575dd058e10ad4c35065e7c3007cc74d142f622b14e168d8a273a2fa8713"}, + {file = "yarl-1.6.2-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:9b48d31f8d881713fd461abfe7acbb4dcfeb47cec3056aa83f2fbcd2244577f7"}, + {file = "yarl-1.6.2-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:1c05ae3d5ea4287470046a2c2754f0a4c171b84ea72c8a691f776eb1753dfb91"}, + {file = "yarl-1.6.2-cp37-cp37m-win_amd64.whl", hash = "sha256:f4f27ff3dd80bc7c402def211a47291ea123d59a23f59fe18fc0e81e3e71f385"}, + {file = "yarl-1.6.2-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:73d4e1e1ef5e52d526c92f07d16329e1678612c6a81dd8101fdcae11a72de15c"}, + {file = "yarl-1.6.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:db643ce2b58a4bd11a82348225c53c76ecdd82bb37cf4c085e6df1b676f4038c"}, + {file = "yarl-1.6.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:d25d3311794e6c71b608d7c47651c8f65eea5ab15358a27f29330b3475e8f8e5"}, + {file = "yarl-1.6.2-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:51c6d3cf7a1f1fbe134bb92f33b7affd94d6de24cd64b466eb12de52120fb8c6"}, + {file = "yarl-1.6.2-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:cd623170c729a865037828e3f99f8ebdb22a467177a539680dfc5670b74c84e2"}, + {file = "yarl-1.6.2-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:c056e86bff5a0b566e0d9fab4f67e83b12ae9cbcd250d334cbe2005bbe8c96f2"}, + {file = "yarl-1.6.2-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:f4c007156732866aa4507d619fe6f8f2748caabed4f66b276ccd97c82572620c"}, + {file = "yarl-1.6.2-cp38-cp38-win_amd64.whl", hash = "sha256:2bb2e21cf062dfbe985c3cd4618bae9f25271efcad9e7be1277861247eee9839"}, + {file = "yarl-1.6.2-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:b99c25ed5c355b35d1e6dae87ac7297a4844a57dc5766b173b88b6163a36eb0d"}, + {file = "yarl-1.6.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2467baf8233f7c64048df37e11879c553943ffe7f373e689711ec2807ea13805"}, + {file = "yarl-1.6.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:e3a0c43a26dfed955b2a06fdc4d51d2c51bc2200aff8ce8faf14e676ea8c8862"}, + {file = "yarl-1.6.2-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:f2f0174cb15435957d3b751093f89aede77df59a499ab7516bbb633b77ead13a"}, + {file = "yarl-1.6.2-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:d695439c201ed340745250f9eb4dfe8d32bf1e680c16477107b8f3ce4bff4fdb"}, + {file = "yarl-1.6.2-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:f57744fc61e118b5d114ae8077d8eb9df4d2d2c11e2af194e21f0c11ed9dcf6c"}, + {file = "yarl-1.6.2-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:d894a2442d2cd20a3b0b0dce5a353d316c57d25a2b445e03f7eac90eee27b8af"}, + {file = "yarl-1.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:076157404db9db4bb3fa9db22db319bbb36d075eeab19ba018ce20ae0cacf037"}, + {file = "yarl-1.6.2.tar.gz", hash = "sha256:c45b49b59a5724869899798e1bbd447ac486215269511d3b76b4c235a1b766b6"}, ] diff --git a/pyproject.toml b/pyproject.toml index 4d4d9368367..a2ea2668ca3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,7 +67,7 @@ pytimeparse = "^1.1.8" django-redis = "^4.12.1" Adyen = "^3.0.0" google-cloud-pubsub = ">=1.7,<3.0" -uvicorn = "^0.11.8" +uvicorn = {extras = ["standard"], version = "^0.12.2"} gunicorn = "^20.0.4" [tool.poetry.dev-dependencies] diff --git a/requirements.txt b/requirements.txt index c6540b0dd40..2fceb728c2a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,137 +1,140 @@ adyen==3.0.0 -amqp==5.0.1 +amqp==5.0.1; python_version >= "3.6" aniso8601==7.0.0 -asgiref==3.2.10 -babel==2.8.0 +asgiref==3.2.10; python_version >= "3.6" +babel==2.8.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") beautifulsoup4==4.7.1 -billiard==3.6.3.0 -boto3==1.15.11 -botocore==1.18.11 +billiard==3.6.3.0; python_version >= "3.6" +boto3==1.16.9 +botocore==1.19.9 braintree==4.4.0 -cachetools==4.1.1 -cairocffi==1.1.0 -cairosvg==2.4.2 -celery==5.0.0 -certifi==2020.6.20 -cffi==1.14.2 -chardet==3.0.4 -click==7.1.2 -click-didyoumean==0.0.3 -click-repl==0.1.6 -cssselect2==0.3.0 -defusedxml==0.6.0 +cachetools==4.1.1; python_version >= "3.5" and python_version < "4.0" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.4.0") +cairocffi==1.1.0; python_version >= "3.6" +cairosvg==2.4.2; python_version >= "3.6" +celery==5.0.1; python_version >= "3.6" +certifi==2020.6.20; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" +cffi==1.14.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0" +chardet==3.0.4; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" +click-didyoumean==0.0.3; python_version >= "3.6" +click-repl==0.1.6; python_version >= "3.6" +click==7.1.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" +colorama==0.4.3; python_version >= "2.7" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_full_version >= "3.5.0" +cssselect2==0.3.0; python_version >= "3.6" +defusedxml==0.6.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" dj-database-url==0.5.0 dj-email-url==1.0.1 -django==3.1.2 django-appconf==1.0.4 django-cache-url==3.1.2 django-countries==6.1.3 -django-filter==2.4.0 -django-js-asset==1.2.2 +django-filter==2.4.0; python_version >= "3.5" +django-js-asset==1.2.2; python_version >= "3.5" django-measurement==3.2.3 -django-mptt==0.11.0 -django-phonenumber-field==5.0.0 -django-prices==2.2.0 +django-mptt==0.11.0; python_version >= "3.5" +django-phonenumber-field==5.0.0; python_version >= "3.5" django-prices-openexchangerates==1.1.0 django-prices-vatlayer==1.1.0 -django-redis==4.12.1 -django-render-block==0.7 -django-storages==1.10.1 +django-prices==2.2.0 +django-redis==4.12.1; python_version >= "3.5" +django-render-block==0.7; python_version >= "3.5" +django-storages==1.10.1; python_version >= "3.5" django-templated-email==2.3.0 django-versatileimagefield==2.0 +django==3.1.2; python_version >= "3.6" draftjs-sanitizer==1.0.0 enmerkar==0.7.1 -et-xmlfile==1.0.1 -faker==4.1.3 -freezegun==0.3.15 -google-api-core==1.22.2 -google-auth==1.21.3 -google-cloud-core==1.4.1 -google-cloud-pubsub==2.1.0 -google-cloud-storage==1.31.2 -google-crc32c==1.0.0; python_version >= "3.5" +et-xmlfile==1.0.1; python_version >= "3.6" +faker==4.14.0; python_version >= "3.5" +freezegun==0.3.15; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") +google-api-core==1.22.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" +google-auth==1.21.3; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.4.0" +google-cloud-core==1.4.1; python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.4.0" +google-cloud-pubsub==2.1.0; python_version >= "3.6" +google-cloud-storage==1.32.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") +google-crc32c==1.0.0; python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.5.0" google-i18n-address==2.4.0 google-measurement-protocol==1.1.0 -google-resumable-media==1.0.0 -googleapis-common-protos==1.52.0 -graphene==2.1.8 +google-resumable-media==1.0.0; python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.5.0" +googleapis-common-protos==1.52.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" graphene-django==2.13.0 graphene-federation==0.1.0 +graphene==2.1.8 graphql-core==2.3.2 graphql-relay==2.0.1 -grpc-google-iam-v1==0.12.3 -grpcio==1.31.0 -gunicorn==20.0.4 +grpc-google-iam-v1==0.12.3; python_version >= "3.6" +grpcio==1.31.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" +gunicorn==20.0.4; python_version >= "3.4" h11==0.9.0 html-to-draftjs==1.0.1 -html5lib==1.1 +html5lib==1.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" httptools==0.1.1; sys_platform != "win32" and sys_platform != "cygwin" and platform_python_implementation != "PyPy" -idna==2.10 +idna==2.10; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" jaeger-client==4.3.0 -jdcal==1.4.1 -jmespath==0.10.0 -jsonfield==3.1.0 -kombu==5.0.2 -libcst==0.3.10 -lxml==4.5.2 -markdown==3.2.2 -maxminddb==2.0.2 +jdcal==1.4.1; python_version >= "3.6" +jmespath==0.10.0; python_version >= "2.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" +jsonfield==3.1.0; python_version >= "3.6" +kombu==5.0.2; python_version >= "3.6" +libcst==0.3.10; python_version >= "3.6" +lxml==4.5.2; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" +markdown==3.3.3; python_version >= "3.6" maxminddb-geolite2==2018.703 +maxminddb==2.0.3; python_version >= "3.6" measurement==3.2.0 -mpmath==1.1.0 -mypy-extensions==0.4.3 -oauthlib==3.1.0 -openpyxl==3.0.5 +mpmath==1.1.0; python_version >= "3.5" +mypy-extensions==0.4.3; python_version >= "3.6" +oauthlib==3.1.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") +openpyxl==3.0.5; python_version >= "3.6" opentracing==2.3.0 -petl==1.6.7 -phonenumberslite==8.12.10 -pillow==7.2.0 +petl==1.6.8; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") +phonenumberslite==8.12.12 +pillow==7.2.0; python_version >= "3.6" prices==1.1.0 promise==2.3 -prompt-toolkit==3.0.7 -proto-plus==1.9.1 -protobuf==3.13.0 -psycopg2-binary==2.8.6 +prompt-toolkit==3.0.7; python_full_version >= "3.6.1" and python_version >= "3.6" +proto-plus==1.9.1; python_version >= "3.6" +protobuf==3.13.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" +psycopg2-binary==2.8.6; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") purl==1.5 -pyasn1==0.4.8 -pyasn1-modules==0.2.8 -pycparser==2.20 +pyasn1-modules==0.2.8; python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.4.0" +pyasn1==0.4.8; python_version >= "3.5" and python_full_version < "3.0.0" and python_version < "4" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.4.0") or python_version >= "3.5" and python_full_version >= "3.4.0" and python_version < "4" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.4.0") +pycparser==2.20; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" pyjwt==1.7.1 -pyphen==0.9.5 -python-dateutil==2.8.1 -python-json-logger==2.0.0 -python-magic==0.4.18 +pyphen==0.9.5; python_version >= "3.6" +python-dateutil==2.8.1; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5" +python-dotenv==0.14.0 +python-json-logger==2.0.1; python_version >= "3.4" python-magic-bin==0.4.14; sys_platform == "win32" +python-magic==0.4.18; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" pytimeparse==1.1.8 -pytz==2020.1 -pyyaml==5.3.1 +pytz==2020.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" +pyyaml==5.3.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" razorpay==1.2.0 -redis==3.5.3 -requests==2.24.0 -rsa==4.6; python_version >= "3.5" +redis==3.5.3; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0" +requests==2.24.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") +rsa==4.6; python_version >= "3.5" and python_version < "4" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.4.0") rx==1.6.1 s3transfer==0.3.3 sentry-sdk==0.17.3 singledispatch==3.4.0.3 -six==1.15.0 -soupsieve==2.0.1 -sqlparse==0.3.1 -stripe==2.54.0 -sympy==1.6.2 +six==1.15.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" +soupsieve==2.0.1; python_version >= "3.5" +sqlparse==0.3.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" +stripe==2.55.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") +sympy==1.6.2; python_version >= "3.5" text-unidecode==1.3 threadloop==1.0.2 thrift==0.13.0 -tinycss2==1.0.2 -tornado==6.0.4 -tqdm==4.50.0 -typing-extensions==3.7.4.3 -typing-inspect==0.6.0 -unidecode==1.1.1 -urllib3==1.25.10 -uvicorn==0.11.8 +tinycss2==1.0.2; python_version >= "3.6" +tornado==6.0.4; python_version >= "3.5" +tqdm==4.51.0; (python_version >= "2.6" and python_full_version < "3.0.0") or (python_full_version >= "3.2.0") +typing-extensions==3.7.4.3; python_version >= "3.6" +typing-inspect==0.6.0; python_version >= "3.6" +unidecode==1.1.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" +urllib3==1.25.10; python_version >= "2.7" and python_full_version < "3.0.0" and python_version != "3.4" or python_full_version >= "3.5.0" and python_version < "4" and python_version != "3.4" +uvicorn==0.12.2 uvloop==0.14.0; sys_platform != "win32" and sys_platform != "cygwin" and platform_python_implementation != "PyPy" -vine==5.0.0 -wcwidth==0.2.5 -weasyprint==51 -webencodings==0.5.1 -websockets==8.1 +vine==5.0.0; python_version >= "3.6" +watchgod==0.6; python_version >= "3.5" +wcwidth==0.2.5; python_full_version >= "3.6.1" and python_version >= "3.6" +weasyprint==52; python_version >= "3.6" +webencodings==0.5.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" +websockets==8.1; python_full_version >= "3.6.1" diff --git a/requirements_dev.txt b/requirements_dev.txt index d704355cbf0..47e83168735 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,204 +1,206 @@ adyen==3.0.0 -amqp==5.0.1 +amqp==5.0.1; python_version >= "3.6" aniso8601==7.0.0 -apipkg==1.5 -appdirs==1.4.4 -asgiref==3.2.10 -astroid==2.4.2 -atomicwrites==1.4.0; sys_platform == "win32" -attrs==20.1.0 -babel==2.8.0 +apipkg==1.5; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" +appdirs==1.4.4; python_version >= "3.6" and python_full_version >= "3.6.1" +asgiref==3.2.10; python_version >= "3.6" +astroid==2.4.2; python_version >= "3.5" +atomicwrites==1.4.0; python_version >= "3.5" and python_full_version < "3.0.0" and sys_platform == "win32" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5") or sys_platform == "win32" and python_version >= "3.5" and python_full_version >= "3.4.0" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5") +attrs==20.1.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" +babel==2.8.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") beautifulsoup4==4.7.1 beautifultable==0.7.0 -billiard==3.6.3.0 -black==19.10b0 -boto3==1.15.11 -botocore==1.18.11 +billiard==3.6.3.0; python_version >= "3.6" +black==19.10b0; python_version >= "3.6" +boto3==1.16.9 +botocore==1.19.9 braintree==4.4.0 -cachetools==4.1.1 -cairocffi==1.1.0 -cairosvg==2.4.2 -celery==5.0.0 -certifi==2020.6.20 -cffi==1.14.2 -cfgv==3.2.0 -chardet==3.0.4 -click==7.1.2 -click-didyoumean==0.0.3 -click-repl==0.1.6 -codecov==2.1.9 -colorama==0.4.3 -coverage==5.3 -cssselect2==0.3.0 -defusedxml==0.6.0 -distlib==0.3.1 +cachetools==4.1.1; python_version >= "3.5" and python_version < "4.0" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.4.0") +cairocffi==1.1.0; python_version >= "3.6" +cairosvg==2.4.2; python_version >= "3.6" +celery==5.0.1; python_version >= "3.6" +certifi==2020.6.20; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" +cffi==1.14.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0" +cfgv==3.2.0; python_full_version >= "3.6.1" +chardet==3.0.4; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" +click-didyoumean==0.0.3; python_version >= "3.6" +click-repl==0.1.6; python_version >= "3.6" +click==7.1.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" +codecov==2.1.10; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") +colorama==0.4.3; python_version >= "3.5" and python_full_version < "3.0.0" and sys_platform == "win32" and platform_system == "Windows" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5") or sys_platform == "win32" and python_full_version >= "3.5.0" and python_version >= "3.5" and platform_system == "Windows" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5") +coverage==5.3; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0" and python_version < "4") +cssselect2==0.3.0; python_version >= "3.6" +defusedxml==0.6.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" +distlib==0.3.1; python_full_version >= "3.6.1" dj-database-url==0.5.0 dj-email-url==1.0.1 -django==3.1.2 django-appconf==1.0.4 django-cache-url==3.1.2 django-countries==6.1.3 -django-debug-toolbar==3.1.1 django-debug-toolbar-request-history==0.1.3 -django-extensions==3.0.9 -django-filter==2.4.0 +django-debug-toolbar==3.1.1; python_version >= "3.5" +django-extensions==3.0.9; python_version >= "3.5" +django-filter==2.4.0; python_version >= "3.5" django-graphiql-debug-toolbar==0.1.4 -django-js-asset==1.2.2 +django-js-asset==1.2.2; python_version >= "3.5" django-measurement==3.2.3 -django-mptt==0.11.0 -django-phonenumber-field==5.0.0 -django-prices==2.2.0 +django-mptt==0.11.0; python_version >= "3.5" +django-phonenumber-field==5.0.0; python_version >= "3.5" django-prices-openexchangerates==1.1.0 django-prices-vatlayer==1.1.0 -django-redis==4.12.1 -django-render-block==0.7 -django-storages==1.10.1 -django-stubs==1.2.0 +django-prices==2.2.0 +django-redis==4.12.1; python_version >= "3.5" +django-render-block==0.7; python_version >= "3.5" +django-storages==1.10.1; python_version >= "3.5" +django-stubs==1.2.0; python_version >= "3.6" django-templated-email==2.3.0 django-versatileimagefield==2.0 +django==3.1.2; python_version >= "3.6" draftjs-sanitizer==1.0.0 enmerkar==0.7.1 -et-xmlfile==1.0.1 -execnet==1.7.1 -faker==4.1.3 -filelock==3.0.12 -flake8==3.8.4 -freezegun==0.3.15 -gitdb==4.0.5 -gitpython==3.1.7 -google-api-core==1.22.2 -google-auth==1.21.3 -google-cloud-core==1.4.1 -google-cloud-pubsub==2.1.0 -google-cloud-storage==1.31.2 -google-crc32c==1.0.0; python_version >= "3.5" +et-xmlfile==1.0.1; python_version >= "3.6" +execnet==1.7.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" +faker==4.14.0; python_version >= "3.5" +filelock==3.0.12; python_full_version >= "3.6.1" +flake8==3.8.4; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") +freezegun==0.3.15; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") +gitdb==4.0.5; python_version >= "3.4" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version < "3.10" and python_version >= "3.4" +gitpython==3.1.7; python_version >= "3.4" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version < "3.10" and python_version >= "3.4" +google-api-core==1.22.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" +google-auth==1.21.3; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.4.0" +google-cloud-core==1.4.1; python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.4.0" +google-cloud-pubsub==2.1.0; python_version >= "3.6" +google-cloud-storage==1.32.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") +google-crc32c==1.0.0; python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.5.0" google-i18n-address==2.4.0 google-measurement-protocol==1.1.0 -google-resumable-media==1.0.0 -googleapis-common-protos==1.52.0 -graphene==2.1.8 +google-resumable-media==1.0.0; python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.5.0" +googleapis-common-protos==1.52.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" graphene-django==2.13.0 graphene-federation==0.1.0 +graphene==2.1.8 graphql-core==2.3.2 graphql-relay==2.0.1 -grpc-google-iam-v1==0.12.3 -grpcio==1.31.0 -gunicorn==20.0.4 +grpc-google-iam-v1==0.12.3; python_version >= "3.6" +grpcio==1.31.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" +gunicorn==20.0.4; python_version >= "3.4" h11==0.9.0 html-to-draftjs==1.0.1 -html5lib==1.1 +html5lib==1.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" httptools==0.1.1; sys_platform != "win32" and sys_platform != "cygwin" and platform_python_implementation != "PyPy" -identify==1.4.30 -idna==2.10 -iniconfig==1.0.1 -isort==4.3.21 +identify==1.4.30; python_full_version >= "3.6.1" +idna==2.10; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" +iniconfig==1.0.1; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5" +isort==4.3.21; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") jaeger-client==4.3.0 -jdcal==1.4.1 -jinja2==2.11.2 -jmespath==0.10.0 -jsonfield==3.1.0 -kombu==5.0.2 -lazy-object-proxy==1.4.3 -libcst==0.3.10 -lxml==4.5.2 -markdown==3.2.2 -markupsafe==1.1.1 -maxminddb==2.0.2 +jdcal==1.4.1; python_version >= "3.6" +jinja2==2.11.2; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" +jmespath==0.10.0; python_version >= "2.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" +jsonfield==3.1.0; python_version >= "3.6" +kombu==5.0.2; python_version >= "3.6" +lazy-object-proxy==1.4.3; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.5" +libcst==0.3.10; python_version >= "3.6" +lxml==4.5.2; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" +markdown==3.3.3; python_version >= "3.6" +markupsafe==1.1.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" maxminddb-geolite2==2018.703 -mccabe==0.6.1 +maxminddb==2.0.3; python_version >= "3.6" +mccabe==0.6.1; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.5" measurement==3.2.0 -mpmath==1.1.0 +mpmath==1.1.0; python_version >= "3.5" multidict==4.7.6; python_version >= "3.6" -mypy==0.740 -mypy-extensions==0.4.3 -nodeenv==1.5.0 -oauthlib==3.1.0 -openpyxl==3.0.5 +mypy-extensions==0.4.3; python_version >= "3.6" +mypy==0.740; python_version >= "3.5" +nodeenv==1.5.0; python_full_version >= "3.6.1" +oauthlib==3.1.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") +openpyxl==3.0.5; python_version >= "3.6" opentracing==2.3.0 -packaging==20.4 -pathspec==0.8.0 -petl==1.6.7 -phonenumberslite==8.12.10 -pillow==7.2.0 -pluggy==0.13.1 -pre-commit==2.7.1 +packaging==20.4; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5" +pathspec==0.8.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" +petl==1.6.8; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") +phonenumberslite==8.12.12 +pillow==7.2.0; python_version >= "3.6" +pluggy==0.13.1; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5" +pre-commit==2.8.2; python_full_version >= "3.6.1" prices==1.1.0 promise==2.3 -prompt-toolkit==3.0.7 -proto-plus==1.9.1 -protobuf==3.13.0 -psycopg2-binary==2.8.6 +prompt-toolkit==3.0.7; python_full_version >= "3.6.1" and python_version >= "3.6" +proto-plus==1.9.1; python_version >= "3.6" +protobuf==3.13.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" +psycopg2-binary==2.8.6; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") purl==1.5 -py==1.9.0 -pyasn1==0.4.8 -pyasn1-modules==0.2.8 -pycodestyle==2.6.0 -pycparser==2.20 -pydocstyle==5.1.1 -pyflakes==2.2.0 +py==1.9.0; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5" +pyasn1-modules==0.2.8; python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.4.0" +pyasn1==0.4.8; python_version >= "3.5" and python_full_version < "3.0.0" and python_version < "4" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.4.0") or python_version >= "3.5" and python_full_version >= "3.4.0" and python_version < "4" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.4.0") +pycodestyle==2.6.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") +pycparser==2.20; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" +pydocstyle==5.1.1; python_version >= "3.5" +pyflakes==2.2.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" pyjwt==1.7.1 -pylint==2.6.0 pylint-celery==0.3 pylint-django==2.3.0 pylint-plugin-utils==0.6 -pyparsing==2.4.7 -pyphen==0.9.5 -pytest==6.1.1 +pylint==2.6.0; python_version >= "3.5" +pyparsing==2.4.7; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.5" +pyphen==0.9.5; python_version >= "3.6" pytest-celery==0.0.0a1 -pytest-cov==2.10.1 -pytest-django==3.10.0 +pytest-cov==2.10.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") pytest-django-queries==1.1.0 -pytest-forked==1.3.0 -pytest-mock==3.3.1 +pytest-django==4.1.0; python_version >= "3.5" +pytest-forked==1.3.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" +pytest-mock==3.3.1; python_version >= "3.5" pytest-vcr==1.0.2 -pytest-xdist==1.34.0 -python-dateutil==2.8.1 -python-json-logger==2.0.0 -python-magic==0.4.18 +pytest-xdist==1.34.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") +pytest==6.1.2; python_version >= "3.5" +python-dateutil==2.8.1; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5" +python-dotenv==0.14.0 +python-json-logger==2.0.1; python_version >= "3.4" python-magic-bin==0.4.14; sys_platform == "win32" -python-slugify==4.0.1 +python-magic==0.4.18; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" +python-slugify==4.0.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "3.10" pytimeparse==1.1.8 -pytz==2020.1 +pytz==2020.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" pywatchman==1.4.1 -pyyaml==5.3.1 +pyyaml==5.3.1; python_full_version >= "3.6.1" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6") and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5") razorpay==1.2.0 -redis==3.5.3 -regex==2020.7.14 -requests==2.24.0 -rsa==4.6; python_version >= "3.5" +redis==3.5.3; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0" +regex==2020.7.14; python_version >= "3.6" +requests==2.24.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") +rsa==4.6; python_version >= "3.5" and python_version < "4" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_version >= "3.5" and python_full_version >= "3.4.0") rx==1.6.1 s3transfer==0.3.3 sentry-sdk==0.17.3 singledispatch==3.4.0.3 -six==1.15.0 -smmap==3.0.4 -snowballstemmer==2.0.0 -soupsieve==2.0.1 -sqlparse==0.3.1 -stripe==2.54.0 -sympy==1.6.2 +six==1.15.0; python_full_version >= "3.6.1" and python_version < "3.10" and python_version >= "3.6" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.5") and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.5") and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0") and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6") +smmap==3.0.4; python_version >= "3.4" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version < "3.10" and python_version >= "3.4" +snowballstemmer==2.0.0; python_version >= "3.5" +soupsieve==2.0.1; python_version >= "3.5" +sqlparse==0.3.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" +stripe==2.55.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") +sympy==1.6.2; python_version >= "3.5" text-unidecode==1.3 threadloop==1.0.2 thrift==0.13.0 -tinycss2==1.0.2 -toml==0.10.1 -tornado==6.0.4 -tox==3.20.0 -tqdm==4.50.0 -transifex-client==0.13.12 -typed-ast==1.4.1 -typing-extensions==3.7.4.3 -typing-inspect==0.6.0 -unidecode==1.1.1 -urllib3==1.25.10 -uvicorn==0.11.8 +tinycss2==1.0.2; python_version >= "3.6" +toml==0.10.1; python_version >= "3.6" and python_full_version >= "3.6.1" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0") and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5") +tornado==6.0.4; python_version >= "3.5" +tox==3.20.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") +tqdm==4.51.0; (python_version >= "2.6" and python_full_version < "3.0.0") or (python_full_version >= "3.2.0") +transifex-client==0.14.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0" and python_version < "3.10") +typed-ast==1.4.1; python_version >= "3.6" +typing-extensions==3.7.4.3; python_version >= "3.6" +typing-inspect==0.6.0; python_version >= "3.6" +unidecode==1.1.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" +urllib3==1.25.10; python_version >= "2.7" and python_full_version < "3.0.0" and python_version != "3.4" or python_full_version >= "3.5.0" and python_version < "3.10" and python_version != "3.4" +uvicorn==0.12.2 uvloop==0.14.0; sys_platform != "win32" and sys_platform != "cygwin" and platform_python_implementation != "PyPy" -vcrpy==4.1.0 -vine==5.0.0 -virtualenv==20.0.31 -wcwidth==0.2.5 -weasyprint==51 -webencodings==0.5.1 -websockets==8.1 -wrapt==1.12.1 +vcrpy==4.1.0; python_version >= "3.5" +vine==5.0.0; python_version >= "3.6" +virtualenv==20.0.31; python_full_version >= "3.6.1" +watchgod==0.6; python_version >= "3.5" +wcwidth==0.2.5; python_full_version >= "3.6.1" and python_version >= "3.6" +weasyprint==52; python_version >= "3.6" +webencodings==0.5.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" +websockets==8.1; python_full_version >= "3.6.1" +wrapt==1.12.1; python_version >= "3.5" yarl==1.5.1; python_version >= "3.6" diff --git a/saleor/graphql/core/tests/test_core.py b/saleor/graphql/core/tests/test_core.py index b5785aa8001..38b9df71eef 100644 --- a/saleor/graphql/core/tests/test_core.py +++ b/saleor/graphql/core/tests/test_core.py @@ -130,21 +130,19 @@ def test_total_count_query(api_client, product): def test_mutation_positive_decimal_input( - staff_api_client, variant, size_attribute, stock, permission_manage_products + staff_api_client, variant, stock, permission_manage_products ): query = """ mutation PositiveDecimalInput( $id: ID!, $cost: PositiveDecimal, $price: PositiveDecimal, - $attributes: [AttributeValueInput], ) { productVariantUpdate( id: $id, input: { costPrice: $cost, price: $price, - attributes: $attributes } ) { errors { @@ -165,12 +163,6 @@ def test_mutation_positive_decimal_input( "price": 15, "cost": 12.12, "quantity": 17, - "attributes": [ - { - "id": graphene.Node.to_global_id("Attribute", size_attribute.pk), - "values": ["S"], - } - ], } response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products] @@ -181,21 +173,19 @@ def test_mutation_positive_decimal_input( def test_mutation_positive_decimal_input_without_arguments( - staff_api_client, variant, size_attribute, permission_manage_products + staff_api_client, variant, permission_manage_products ): query = """ mutation ProductVariantUpdate( $id: ID!, $price: PositiveDecimal, $costPrice: PositiveDecimal, - $attributes: [AttributeValueInput], ) { productVariantUpdate( id: $id, input: { costPrice: $costPrice, price: $price, - attributes: $attributes, } ) { errors { @@ -214,12 +204,6 @@ def test_mutation_positive_decimal_input_without_arguments( "id": graphene.Node.to_global_id("ProductVariant", variant.id), "cost": 12.12, "price": 15, - "attributes": [ - { - "id": graphene.Node.to_global_id("Attribute", size_attribute.pk), - "values": ["S"], - } - ], } response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products] diff --git a/saleor/graphql/order/dataloaders.py b/saleor/graphql/order/dataloaders.py new file mode 100644 index 00000000000..db087d02224 --- /dev/null +++ b/saleor/graphql/order/dataloaders.py @@ -0,0 +1,17 @@ +from collections import defaultdict + +from ...warehouse.models import Allocation +from ..core.dataloaders import DataLoader + + +class AllocationsByOrderLineIdLoader(DataLoader): + context_key = "allocations_by_orderline_id" + + def batch_load(self, keys): + allocations = Allocation.objects.filter(order_line__pk__in=keys) + order_lines_to_allocations = defaultdict(list) + + for allocation in allocations: + order_lines_to_allocations[allocation.order_line_id].append(allocation) + + return [order_lines_to_allocations[order_line_id] for order_line_id in keys] diff --git a/saleor/graphql/order/mutations/draft_orders.py b/saleor/graphql/order/mutations/draft_orders.py index 145704daab5..4f5b494726d 100644 --- a/saleor/graphql/order/mutations/draft_orders.py +++ b/saleor/graphql/order/mutations/draft_orders.py @@ -127,7 +127,6 @@ def clean_input(cls, info, instance, data): @staticmethod def _save_addresses(info, instance: models.Order, cleaned_input): - # Create the draft creation event shipping_address = cleaned_input.get("shipping_address") if shipping_address: shipping_address.save() @@ -206,7 +205,7 @@ def save(cls, info, instance, cleaned_input): class DraftOrderUpdate(DraftOrderCreate): class Arguments: - id = graphene.ID(required=True, description="ID of an order to update.") + id = graphene.ID(required=True, description="ID of a draft order to update.") input = DraftOrderInput( required=True, description="Fields required to update an order." ) @@ -218,6 +217,21 @@ class Meta: error_type_class = OrderError error_type_field = "order_errors" + @classmethod + def get_instance(cls, info, **data): + instance = super().get_instance(info, **data) + if instance.status != OrderStatus.DRAFT: + raise ValidationError( + { + "id": ValidationError( + "Provided order id belongs to non-draft order. " + "Use `orderUpdate` mutation instead.", + code=OrderErrorCode.INVALID, + ) + } + ) + return instance + class DraftOrderDelete(ModelDeleteMutation): class Arguments: diff --git a/saleor/graphql/order/mutations/orders.py b/saleor/graphql/order/mutations/orders.py index b92c6fdc40c..183d3b66959 100644 --- a/saleor/graphql/order/mutations/orders.py +++ b/saleor/graphql/order/mutations/orders.py @@ -1,10 +1,11 @@ import graphene from django.core.exceptions import ValidationError +from django.db import transaction from ....account.models import User from ....core.permissions import OrderPermissions from ....core.taxes import zero_taxed_money -from ....order import events, models +from ....order import OrderStatus, events, models from ....order.actions import ( cancel_order, clean_mark_order_as_paid, @@ -24,7 +25,7 @@ from ...core.utils import validate_required_string_field from ...meta.deprecated.mutations import ClearMetaBaseMutation, UpdateMetaBaseMutation from ...meta.deprecated.types import MetaInput, MetaPath -from ...order.mutations.draft_orders import DraftOrderUpdate +from ...order.mutations.draft_orders import DraftOrderCreate from ...order.types import Order, OrderEvent from ...shipping.types import ShippingMethod @@ -138,7 +139,7 @@ class OrderUpdateInput(graphene.InputObjectType): shipping_address = AddressInput(description="Shipping address of the customer.") -class OrderUpdate(DraftOrderUpdate): +class OrderUpdate(DraftOrderCreate): class Arguments: id = graphene.ID(required=True, description="ID of an order to update.") input = OrderUpdateInput( @@ -165,12 +166,29 @@ def clean_input(cls, info, instance, data): return cleaned_input @classmethod + def get_instance(cls, info, **data): + instance = super().get_instance(info, **data) + if instance.status == OrderStatus.DRAFT: + raise ValidationError( + { + "id": ValidationError( + "Provided order id belongs to draft order. " + "Use `draftOrderUpdate` mutation instead.", + code=OrderErrorCode.INVALID, + ) + } + ) + return instance + + @classmethod + @transaction.atomic def save(cls, info, instance, cleaned_input): - super().save(info, instance, cleaned_input) + cls._save_addresses(info, instance, cleaned_input) if instance.user_email: user = User.objects.filter(email=instance.user_email).first() instance.user = user instance.save() + info.context.plugins.order_updated(instance) class OrderUpdateShippingInput(graphene.InputObjectType): diff --git a/saleor/graphql/order/tests/test_order.py b/saleor/graphql/order/tests/test_order.py index ec4da8367ad..eb2167975f4 100644 --- a/saleor/graphql/order/tests/test_order.py +++ b/saleor/graphql/order/tests/test_order.py @@ -101,6 +101,13 @@ def test_orderline_query(staff_api_client, permission_manage_orders, fulfilled_o id } quantity + allocations { + id + quantity + warehouse { + id + } + } unitPrice { currency gross { @@ -126,23 +133,82 @@ def test_orderline_query(staff_api_client, permission_manage_orders, fulfilled_o response = staff_api_client.post_graphql(query) content = get_graphql_content(response) order_data = content["data"]["orders"]["edges"][0]["node"] - assert order_data["lines"][0]["thumbnail"] is None + first_order_data_line = order_data["lines"][0] variant_id = graphene.Node.to_global_id("ProductVariant", line.variant.pk) - assert order_data["lines"][0]["variant"]["id"] == variant_id - assert order_data["lines"][0]["quantity"] == line.quantity - assert order_data["lines"][0]["unitPrice"]["currency"] == line.unit_price.currency + + assert first_order_data_line["thumbnail"] is None + assert first_order_data_line["variant"]["id"] == variant_id + assert first_order_data_line["quantity"] == line.quantity + assert first_order_data_line["unitPrice"]["currency"] == line.unit_price.currency + expected_unit_price = Money( - amount=str(order_data["lines"][0]["unitPrice"]["gross"]["amount"]), + amount=str(first_order_data_line["unitPrice"]["gross"]["amount"]), currency="USD", ) - assert order_data["lines"][0]["totalPrice"]["currency"] == line.unit_price.currency + assert first_order_data_line["totalPrice"]["currency"] == line.unit_price.currency assert expected_unit_price == line.unit_price.gross + expected_total_price = Money( - amount=str(order_data["lines"][0]["totalPrice"]["gross"]["amount"]), + amount=str(first_order_data_line["totalPrice"]["gross"]["amount"]), currency="USD", ) assert expected_total_price == line.unit_price.gross * line.quantity + allocation = line.allocations.first() + allocation_id = graphene.Node.to_global_id("Allocation", allocation.pk) + warehouse_id = graphene.Node.to_global_id( + "Warehouse", allocation.stock.warehouse.pk + ) + assert first_order_data_line["allocations"] == [ + {"id": allocation_id, "quantity": 0, "warehouse": {"id": warehouse_id}} + ] + + +def test_order_line_with_allocations( + staff_api_client, permission_manage_orders, order_with_lines, +): + # given + order = order_with_lines + query = """ + query OrdersQuery { + orders(first: 1) { + edges { + node { + lines { + id + allocations { + id + quantity + warehouse { + id + } + } + } + } + } + } + } + """ + staff_api_client.user.user_permissions.add(permission_manage_orders) + + # when + response = staff_api_client.post_graphql(query) + + # then + content = get_graphql_content(response) + lines = content["data"]["orders"]["edges"][0]["node"]["lines"] + + for line in lines: + _, _id = graphene.Node.from_global_id(line["id"]) + order_line = order.lines.get(pk=_id) + allocations_from_query = { + allocation["quantity"] for allocation in line["allocations"] + } + allocations_from_db = set( + order_line.allocations.values_list("quantity_allocated", flat=True) + ) + assert allocations_from_query == allocations_from_db + def test_order_query( staff_api_client, permission_manage_orders, fulfilled_order, shipping_zone @@ -808,9 +874,9 @@ def test_draft_order_create_tax_error( def test_draft_order_update( - staff_api_client, permission_manage_orders, order_with_lines, voucher + staff_api_client, permission_manage_orders, draft_order, voucher ): - order = order_with_lines + order = draft_order assert not order.voucher assert not order.customer_note query = DRAFT_ORDER_UPDATE_MUTATION @@ -829,18 +895,36 @@ def test_draft_order_update( assert order.customer_note == customer_note +def test_draft_order_update_with_non_draft_order( + staff_api_client, permission_manage_orders, order_with_lines, voucher +): + order = order_with_lines + query = DRAFT_ORDER_UPDATE_MUTATION + order_id = graphene.Node.to_global_id("Order", order.id) + voucher_id = graphene.Node.to_global_id("Voucher", voucher.id) + customer_note = "Test customer note" + variables = {"id": order_id, "voucher": voucher_id, "customerNote": customer_note} + response = staff_api_client.post_graphql( + query, variables, permissions=[permission_manage_orders] + ) + content = get_graphql_content(response) + error = content["data"]["draftOrderUpdate"]["orderErrors"][0] + assert error["field"] == "id" + assert error["code"] == OrderErrorCode.INVALID.name + + @patch("saleor.graphql.order.mutations.draft_orders.update_order_prices") def test_draft_order_update_tax_error( update_order_prices_mock, staff_api_client, permission_manage_orders, - order_with_lines, + draft_order, voucher, graphql_address_data, ): err_msg = "Test error" update_order_prices_mock.side_effect = TaxError(err_msg) - order = order_with_lines + order = draft_order assert not order.voucher assert not order.customer_note query = DRAFT_ORDER_UPDATE_MUTATION @@ -1591,30 +1675,36 @@ def test_require_draft_order_when_removing_lines( assert data["errors"] +ORDER_UPDATE_MUTATION = """ + mutation orderUpdate($id: ID!, $email: String, $address: AddressInput) { + orderUpdate( + id: $id, input: { + userEmail: $email, + shippingAddress: $address, + billingAddress: $address}) { + orderErrors { + field + code + } + order { + userEmail + } + } + } +""" + + +@patch("saleor.plugins.base_plugin.BasePlugin.order_updated") def test_order_update( - staff_api_client, permission_manage_orders, order_with_lines, graphql_address_data + plugin_mock, + staff_api_client, + permission_manage_orders, + order_with_lines, + graphql_address_data, ): order = order_with_lines order.user = None order.save() - query = """ - mutation orderUpdate( - $id: ID!, $email: String, $address: AddressInput) { - orderUpdate( - id: $id, input: { - userEmail: $email, - shippingAddress: $address, - billingAddress: $address}) { - errors { - field - message - } - order { - userEmail - } - } - } - """ email = "not_default@example.com" assert not order.user_email == email assert not order.shipping_address.first_name == graphql_address_data["firstName"] @@ -1622,10 +1712,10 @@ def test_order_update( order_id = graphene.Node.to_global_id("Order", order.id) variables = {"id": order_id, "email": email, "address": graphql_address_data} response = staff_api_client.post_graphql( - query, variables, permissions=[permission_manage_orders] + ORDER_UPDATE_MUTATION, variables, permissions=[permission_manage_orders] ) content = get_graphql_content(response) - assert not content["data"]["orderUpdate"]["errors"] + assert not content["data"]["orderUpdate"]["orderErrors"] data = content["data"]["orderUpdate"]["order"] assert data["userEmail"] == email @@ -1637,6 +1727,31 @@ def test_order_update( assert order.user_email == email assert order.user is None assert order.status == OrderStatus.UNFULFILLED + assert plugin_mock.called is True + + +@patch("saleor.plugins.base_plugin.BasePlugin.order_updated") +def test_order_update_with_draft_order( + plugin_mock, + staff_api_client, + permission_manage_orders, + draft_order, + graphql_address_data, +): + order = draft_order + order.user = None + order.save() + email = "not_default@example.com" + order_id = graphene.Node.to_global_id("Order", order.id) + variables = {"id": order_id, "email": email, "address": graphql_address_data} + response = staff_api_client.post_graphql( + ORDER_UPDATE_MUTATION, variables, permissions=[permission_manage_orders] + ) + content = get_graphql_content(response) + error = content["data"]["orderUpdate"]["orderErrors"][0] + assert error["field"] == "id" + assert error["code"] == OrderErrorCode.INVALID.name + assert plugin_mock.called is False def test_order_update_anonymous_user_no_user_email( diff --git a/saleor/graphql/order/types.py b/saleor/graphql/order/types.py index a2e57ebd079..07fa449ed76 100644 --- a/saleor/graphql/order/types.py +++ b/saleor/graphql/order/types.py @@ -4,7 +4,7 @@ from ...core.anonymize import obfuscate_address, obfuscate_email from ...core.exceptions import PermissionDenied -from ...core.permissions import AccountPermissions, OrderPermissions +from ...core.permissions import AccountPermissions, OrderPermissions, ProductPermissions from ...core.taxes import display_gross_prices from ...graphql.utils import get_user_or_app_from_context from ...order import OrderStatus, models @@ -18,7 +18,7 @@ from ..core.connection import CountableDjangoObjectType from ..core.types.common import Image from ..core.types.money import Money, TaxedMoney -from ..decorators import permission_required +from ..decorators import one_of_permissions_required, permission_required from ..giftcard.types import GiftCard from ..invoice.types import Invoice from ..meta.deprecated.resolvers import resolve_meta, resolve_private_meta @@ -26,7 +26,8 @@ from ..payment.types import OrderAction, Payment, PaymentChargeStatusEnum from ..product.types import ProductVariant from ..shipping.types import ShippingMethod -from ..warehouse.types import Warehouse +from ..warehouse.types import Allocation, Warehouse +from .dataloaders import AllocationsByOrderLineIdLoader from .enums import OrderEventsEmailsEnum, OrderEventsEnum from .utils import validate_draft_order @@ -255,6 +256,10 @@ class OrderLine(CountableDjangoObjectType): translated_variant_name = graphene.String( required=True, description="Variant name in the customer's language" ) + allocations = graphene.List( + graphene.NonNull(Allocation), + description="List of allocations across warehouses.", + ) class Meta: description = "Represents order line of particular order." @@ -299,6 +304,13 @@ def resolve_translated_product_name(root: models.OrderLine, _info): def resolve_translated_variant_name(root: models.OrderLine, _info): return root.translated_variant_name + @staticmethod + @one_of_permissions_required( + [ProductPermissions.MANAGE_PRODUCTS, OrderPermissions.MANAGE_ORDERS] + ) + def resolve_allocations(root: models.OrderLine, info): + return AllocationsByOrderLineIdLoader(info.context).load(root.id) + class Order(CountableDjangoObjectType): fulfillments = graphene.List( diff --git a/saleor/graphql/plugins/tests/test_plugins.py b/saleor/graphql/plugins/tests/test_plugins.py index f5504d1463d..cf0727c5148 100644 --- a/saleor/graphql/plugins/tests/test_plugins.py +++ b/saleor/graphql/plugins/tests/test_plugins.py @@ -252,36 +252,38 @@ def test_query_plugin_configuration_as_customer_user(user_api_client, settings): PLUGIN_UPDATE_MUTATION = """ - mutation pluginUpdate( - $id: ID!, - $active: Boolean, - $configuration: [ConfigurationItemInput] - ){pluginUpdate( - id:$id, - input:{active: $active, configuration: $configuration} - ){ - plugin{ - name - active - configuration{ + mutation pluginUpdate( + $id: ID! + $active: Boolean + $configuration: [ConfigurationItemInput] + ) { + pluginUpdate( + id: $id + input: { active: $active, configuration: $configuration } + ) { + plugin { name - value - type - helpText - label - } + description + active + configuration { + name + value + type + helpText + label + } } - errors{ - field - message + errors { + field + message } pluginsErrors { - field - code + field + code } - } } - """ + } +""" @pytest.mark.parametrize( @@ -310,6 +312,11 @@ def test_plugin_configuration_update( ) content = get_graphql_content(response) + plugin_data = content["data"]["pluginUpdate"]["plugin"] + + assert plugin_data["name"] == plugin.PLUGIN_NAME + assert plugin_data["description"] == plugin.PLUGIN_DESCRIPTION + plugin = PluginConfiguration.objects.get(identifier=PluginSample.PLUGIN_ID) assert plugin.active == active @@ -321,7 +328,7 @@ def test_plugin_configuration_update( assert second_configuration_item["name"] == old_configuration[1]["name"] assert second_configuration_item["value"] == old_configuration[1]["value"] - configuration = content["data"]["pluginUpdate"]["plugin"]["configuration"] + configuration = plugin_data["configuration"] assert configuration is not None assert configuration[0]["name"] == updated_configuration_item["name"] assert configuration[0]["value"] == updated_configuration_item["value"] diff --git a/saleor/graphql/product/dataloaders/attributes.py b/saleor/graphql/product/dataloaders/attributes.py index 4a552c2a1d7..4b2e5b6277f 100644 --- a/saleor/graphql/product/dataloaders/attributes.py +++ b/saleor/graphql/product/dataloaders/attributes.py @@ -12,6 +12,7 @@ AttributeVariant, ) from ...core.dataloaders import DataLoader +from ...utils import get_user_or_app_from_context from .products import ProductByIdLoader, ProductVariantByIdLoader @@ -46,8 +47,10 @@ def batch_load(self, keys): if not self.model_name: raise ValueError("Provide a model_name for this dataloader.") - user = self.user - if user.is_active and user.has_perm(ProductPermissions.MANAGE_PRODUCTS): + requestor = get_user_or_app_from_context(self.context) + if requestor.is_active and requestor.has_perm( + ProductPermissions.MANAGE_PRODUCTS + ): qs = self.model_name.objects.all() else: qs = self.model_name.objects.filter(attribute__visible_in_storefront=True) @@ -100,8 +103,10 @@ class AttributeProductsByProductTypeIdLoader(DataLoader): context_key = "attributeproducts_by_producttype" def batch_load(self, keys): - user = self.user - if user.is_active and user.has_perm(ProductPermissions.MANAGE_PRODUCTS): + requestor = get_user_or_app_from_context(self.context) + if requestor.is_active and requestor.has_perm( + ProductPermissions.MANAGE_PRODUCTS + ): qs = AttributeProduct.objects.all() else: qs = AttributeProduct.objects.filter(attribute__visible_in_storefront=True) @@ -118,8 +123,10 @@ class AttributeVariantsByProductTypeIdLoader(DataLoader): context_key = "attributevariants_by_producttype" def batch_load(self, keys): - user = self.user - if user.is_active and user.has_perm(ProductPermissions.MANAGE_PRODUCTS): + requestor = get_user_or_app_from_context(self.context) + if requestor.is_active and requestor.has_perm( + ProductPermissions.MANAGE_PRODUCTS + ): qs = AttributeVariant.objects.all() else: qs = AttributeVariant.objects.filter(attribute__visible_in_storefront=True) @@ -136,8 +143,10 @@ class AssignedProductAttributesByProductIdLoader(DataLoader): context_key = "assignedproductattributes_by_product" def batch_load(self, keys): - user = self.user - if user.is_active and user.has_perm(ProductPermissions.MANAGE_PRODUCTS): + requestor = get_user_or_app_from_context(self.context) + if requestor.is_active and requestor.has_perm( + ProductPermissions.MANAGE_PRODUCTS + ): qs = AssignedProductAttribute.objects.all() else: qs = AssignedProductAttribute.objects.filter( @@ -156,8 +165,10 @@ class AssignedVariantAttributesByProductVariantId(DataLoader): context_key = "assignedvariantattributes_by_productvariant" def batch_load(self, keys): - user = self.user - if user.is_active and user.has_perm(ProductPermissions.MANAGE_PRODUCTS): + requestor = get_user_or_app_from_context(self.context) + if requestor.is_active and requestor.has_perm( + ProductPermissions.MANAGE_PRODUCTS + ): qs = AssignedVariantAttribute.objects.all() else: qs = AssignedVariantAttribute.objects.filter( @@ -244,7 +255,7 @@ class SelectedAttributesByProductIdLoader(DataLoader): context_key = "selectedattributes_by_product" def batch_load(self, keys): - def with_products_and_assigned_attributed(result): + def with_products_and_assigned_attributes(result): products, product_attributes = result assigned_product_attribute_ids = [ a.id for attrs in product_attributes for a in attrs @@ -316,7 +327,7 @@ def with_attributes(attributes): ).load_many(keys) return Promise.all([products, assigned_attributes]).then( - with_products_and_assigned_attributed + with_products_and_assigned_attributes ) diff --git a/saleor/graphql/product/dataloaders/products.py b/saleor/graphql/product/dataloaders/products.py index a124d85208f..d493503cba5 100644 --- a/saleor/graphql/product/dataloaders/products.py +++ b/saleor/graphql/product/dataloaders/products.py @@ -11,6 +11,7 @@ VariantImage, ) from ...core.dataloaders import DataLoader +from ...utils import get_user_or_app_from_context class CategoryByIdLoader(DataLoader): @@ -25,7 +26,8 @@ class ProductByIdLoader(DataLoader): context_key = "product_by_id" def batch_load(self, keys): - products = Product.objects.visible_to_user(self.user).in_bulk(keys) + requestor = get_user_or_app_from_context(self.context) + products = Product.objects.visible_to_user(requestor).in_bulk(keys) return [products.get(product_id) for product_id in keys] diff --git a/saleor/graphql/product/mutations/products.py b/saleor/graphql/product/mutations/products.py index 8ca9a60e683..6d60a1259b0 100644 --- a/saleor/graphql/product/mutations/products.py +++ b/saleor/graphql/product/mutations/products.py @@ -1206,11 +1206,6 @@ class Meta: def clean_attributes( cls, attributes: dict, product_type: models.ProductType ) -> T_INPUT_MAP: - if not attributes: - raise ValidationError( - "All attributes must take a value.", ProductErrorCode.REQUIRED.value - ) - attributes_qs = product_type.variant_attributes attributes = AttributeAssignmentMixin.clean_input( attributes, attributes_qs, is_variant=True @@ -1300,14 +1295,21 @@ def clean_input( # We need to transform them into the format they're stored in the # `Product` model, which is HStore field that maps attribute's PK to # the value's PK. - attributes = cleaned_input.get("attributes", []) + attributes = cleaned_input.get("attributes") try: - cls.validate_duplicated_attribute_values( - attributes, used_attribute_values, instance - ) - cleaned_input["attributes"] = cls.clean_attributes( - attributes, product_type - ) + if attributes: + cls.validate_duplicated_attribute_values( + attributes, used_attribute_values, instance + ) + cleaned_input["attributes"] = cls.clean_attributes( + attributes, product_type + ) + elif not instance.pk and not attributes: + # if attributes were not provided on creation + raise ValidationError( + "All attributes must take a value.", + ProductErrorCode.REQUIRED.value, + ) except ValidationError as exc: raise ValidationError({"attributes": exc}) diff --git a/saleor/graphql/product/tests/test_collection.py b/saleor/graphql/product/tests/test_collection.py index 58101e73a70..ffb380025ce 100644 --- a/saleor/graphql/product/tests/test_collection.py +++ b/saleor/graphql/product/tests/test_collection.py @@ -192,6 +192,13 @@ def test_collections_query( edges { node { id + attributes { + attribute { + values { + slug + } + } + } } } } @@ -229,6 +236,47 @@ def test_filter_collection_products(user_api_client, product_list, collection): } +def test_filter_collection_products_by_multiple_attributes( + user_api_client, + collection, + product_with_two_variants, + product_with_multiple_values_attributes, +): + # given + collection.products.set( + [product_with_two_variants, product_with_multiple_values_attributes] + ) + assert collection.products.count() == 2 + + filters = { + "attributes": [{"slug": "modes", "values": ["eco"]}], + } + variables = { + "id": graphene.Node.to_global_id("Collection", collection.pk), + "filters": filters, + } + + # when + response = user_api_client.post_graphql( + GET_FILTERED_PRODUCTS_COLLECTION_QUERY, variables + ) + + # then + content = get_graphql_content(response) + products_data = content["data"]["collection"]["products"]["edges"] + product = products_data[0]["node"] + + _, _id = graphene.Node.from_global_id(product["id"]) + + assert len(products_data) == 1 + assert product["id"] == graphene.Node.to_global_id( + "Product", product_with_multiple_values_attributes.pk + ) + assert product["attributes"] == [ + {"attribute": {"values": [{"slug": "eco"}, {"slug": "power"}]}} + ] + + CREATE_COLLECTION_MUTATION = """ mutation createCollection( $name: String!, $slug: String, $description: String, diff --git a/saleor/graphql/product/tests/test_product.py b/saleor/graphql/product/tests/test_product.py index 63ed84c0743..da9f961b054 100644 --- a/saleor/graphql/product/tests/test_product.py +++ b/saleor/graphql/product/tests/test_product.py @@ -63,6 +63,28 @@ def query_products_with_filter(): return query +@pytest.fixture +def query_products_with_attributes(): + query = """ + query { + products(first:5) { + edges{ + node{ + id + name + attributes { + attribute { + id + } + } + } + } + } + } + """ + return query + + @pytest.fixture def query_collections_with_filter(): query = """ @@ -772,6 +794,34 @@ def test_products_query_with_filter_category_and_search( assert products[0]["node"]["name"] == product.name +def test_products_with_variants_query_as_app( + query_products_with_attributes, + app_api_client, + product_with_multiple_values_attributes, + permission_manage_products, +): + product = product_with_multiple_values_attributes + attribute = product.attributes.first().attribute + attribute.visible_in_storefront = False + attribute.save() + second_product = product + second_product.id = None + second_product.slug = "second-product" + second_product.save() + product.save() + + app_api_client.app.permissions.add(permission_manage_products) + response = app_api_client.post_graphql(query_products_with_attributes) + content = get_graphql_content(response) + products = content["data"]["products"]["edges"] + assert len(products) == 2 + attribute_id = graphene.Node.to_global_id("Attribute", attribute.id) + for response_product in products: + attrs = response_product["node"]["attributes"] + assert len(attrs) == 1 + assert attrs[0]["attribute"]["id"] == attribute_id + + @pytest.mark.parametrize( "products_filter", [ diff --git a/saleor/graphql/product/tests/test_product_minimal_variant_price.py b/saleor/graphql/product/tests/test_product_minimal_variant_price.py index ebe7bf95905..964387c7923 100644 --- a/saleor/graphql/product/tests/test_product_minimal_variant_price.py +++ b/saleor/graphql/product/tests/test_product_minimal_variant_price.py @@ -78,20 +78,17 @@ def test_product_variant_update_updates_minimal_variant_price( mock_update_product_minimal_variant_price_task, staff_api_client, product, - size_attribute, permission_manage_products, ): query = """ mutation ProductVariantUpdate( $id: ID!, $price: PositiveDecimal, - $attributes: [AttributeValueInput], ) { productVariantUpdate( id: $id, input: { price: $price, - attributes: $attributes } ) { productVariant { @@ -106,12 +103,10 @@ def test_product_variant_update_updates_minimal_variant_price( """ variant = product.variants.first() variant_id = to_global_id("ProductVariant", variant.pk) - attribute_id = to_global_id("Attribute", size_attribute.pk) price = "1.99" variables = { "id": variant_id, "price": price, - "attributes": [{"id": attribute_id, "values": ["S"]}], } response = staff_api_client.post_graphql( query, variables, permissions=[permission_manage_products] diff --git a/saleor/graphql/product/types/products.py b/saleor/graphql/product/types/products.py index 4adab7533ed..c77aad4b500 100644 --- a/saleor/graphql/product/types/products.py +++ b/saleor/graphql/product/types/products.py @@ -755,7 +755,7 @@ def resolve_weight(root: models.ProductType, _info, **_kwargs): @key(fields="id") class Collection(CountableDjangoObjectType): - products = PrefetchingConnectionField( + products = FilterInputConnectionField( Product, filter=ProductFilterInput(description="Filtering options for products."), sort_by=ProductOrder(description="Sort products."), diff --git a/saleor/graphql/schema.graphql b/saleor/graphql/schema.graphql index a839becb3a1..a5a2148cef1 100644 --- a/saleor/graphql/schema.graphql +++ b/saleor/graphql/schema.graphql @@ -195,6 +195,12 @@ type AddressValidationData { postalCodePrefix: String } +type Allocation implements Node { + id: ID! + quantity: Int! + warehouse: Warehouse! +} + type App implements Node & ObjectWithMetadata { id: ID! name: String @@ -2252,6 +2258,7 @@ enum LanguageCodeEnum { IS IT JA + KA KM KO LT @@ -3142,6 +3149,7 @@ type OrderLine implements Node { variant: ProductVariant translatedProductName: String! translatedVariantName: String! + allocations: [Allocation!] } input OrderLineCreateInput { diff --git a/saleor/graphql/warehouse/types.py b/saleor/graphql/warehouse/types.py index 70063bfe09b..6274be2c652 100644 --- a/saleor/graphql/warehouse/types.py +++ b/saleor/graphql/warehouse/types.py @@ -90,3 +90,30 @@ def resolve_quantity_allocated(root, *_args): return root.allocations.aggregate( quantity_allocated=Coalesce(Sum("quantity_allocated"), 0) )["quantity_allocated"] + + +class Allocation(CountableDjangoObjectType): + quantity = graphene.Int(required=True, description="Quantity allocated for orders.") + warehouse = graphene.Field( + Warehouse, required=True, description="The warehouse were items were allocated." + ) + + class Meta: + description = "Represents allocation." + model = models.Allocation + interfaces = [graphene.relay.Node] + only_fields = ["id"] + + @staticmethod + @one_of_permissions_required( + [ProductPermissions.MANAGE_PRODUCTS, OrderPermissions.MANAGE_ORDERS] + ) + def resolve_warehouse(root, *_args): + return root.stock.warehouse + + @staticmethod + @one_of_permissions_required( + [ProductPermissions.MANAGE_PRODUCTS, OrderPermissions.MANAGE_ORDERS] + ) + def resolve_quantity(root, *_args): + return root.quantity_allocated diff --git a/saleor/payment/gateways/adyen/plugin.py b/saleor/payment/gateways/adyen/plugin.py index 435528ad00f..13784e0ef5c 100644 --- a/saleor/payment/gateways/adyen/plugin.py +++ b/saleor/payment/gateways/adyen/plugin.py @@ -11,6 +11,7 @@ from ....checkout.models import Checkout from ....core.utils import build_absolute_uri from ....core.utils.url import prepare_url +from ....order.events import external_notification_event from ....plugins.base_plugin import BasePlugin, ConfigurationTypeField from ... import PaymentError, TransactionKind from ...interface import GatewayConfig, GatewayResponse, PaymentData, PaymentGateway @@ -54,7 +55,6 @@ class AdyenGatewayPlugin(BasePlugin): {"name": "api-key", "value": None}, {"name": "supported-currencies", "value": ""}, {"name": "client-key", "value": ""}, - {"name": "origin-url", "value": ""}, {"name": "live", "value": ""}, {"name": "adyen-auto-capture", "value": True}, {"name": "auto-capture", "value": False}, @@ -96,19 +96,6 @@ class AdyenGatewayPlugin(BasePlugin): ), "label": "Client Key", }, - "origin-url": { - "type": ConfigurationTypeField.STRING, - "help_text": ( - "The origin URL of the page where you are rendering the Drop-in. This " - "should not include subdirectories and a trailing slash. For example, " - "if you are rendering the Drop-in on " - "https://your-company.com/checkout/payment, specify here: " - "https://your-company.com. For more details see: " - "https://docs.adyen.com/checkout/drop-in-web" - "Not required for Android or iOS app." - ), - "label": "Origin URL", - }, "live": { "type": ConfigurationTypeField.STRING, "help_text": ( @@ -176,10 +163,10 @@ class AdyenGatewayPlugin(BasePlugin): "Saleor uses 3D Secure redirect authentication by default. If you want" " to use native 3D Secure authentication, enable this option. For more" " details see Adyen documentation: native - " - "https://docs.adyen.com/checkout/3d-secure/redirect-3ds2-3ds1, redirect" + "https://docs.adyen.com/checkout/3d-secure/native-3ds2, redirect" " - https://docs.adyen.com/checkout/3d-secure/redirect-3ds2-3ds1" ), - "label": "Enable native 3d secure", + "label": "Enable native 3D Secure", }, } @@ -194,7 +181,6 @@ def __init__(self, *args, **kwargs): "api_key": configuration["api-key"], "merchant_account": configuration["merchant-account"], "client_key": configuration["client-key"], - "origin_url": configuration["origin-url"], "live": configuration["live"], "webhook_hmac": configuration["hmac-secret-key"], "webhook_user": configuration["notification-user"], @@ -279,7 +265,6 @@ def process_payment( payment_information, return_url=return_url, merchant_account=self.config.connection_params["merchant_account"], - origin_url=self.config.connection_params["origin_url"], native_3d_secure=self.config.connection_params["enable_native_3d_secure"], ) result = api_call(request_data, self.adyen.checkout.payments) @@ -349,20 +334,25 @@ def _process_additional_action(self, payment_information: "PaymentData", kind: s result = api_call(additional_data, self.adyen.checkout.payments_details) result_code = result.message["resultCode"].strip().lower() is_success = result_code not in FAILED_STATUSES - + action_required = "action" in result.message if result_code in PENDING_STATUSES: kind = TransactionKind.PENDING - elif is_success and config.auto_capture: + elif is_success and config.auto_capture and not action_required: # For enabled auto_capture on Saleor side we need to proceed an additional # action - response = self.capture_payment(payment_information, None) - is_success = response.is_success + kind = TransactionKind.CAPTURE + result = call_capture( + payment_information=payment_information, + merchant_account=self.config.connection_params["merchant_account"], + token=result.message.get("pspReference"), + adyen_client=self.adyen, + ) payment_method_info = get_payment_method_info(payment_information, result) action = result.message.get("action") return GatewayResponse( is_success=is_success, - action_required="action" in result.message, + action_required=action_required, action_required_data=action, kind=kind, amount=payment_information.amount, @@ -484,12 +474,24 @@ def refund_payment( ) result = api_call(request, self.adyen.payment.refund) + amount = payment_information.amount + currency = payment_information.currency + msg = f"Adyen: Refund for amount {amount}{currency} has been requested." + external_notification_event( + order=transaction.payment.order, # type: ignore + user=None, + message=msg, + parameters={ + "service": transaction.payment.gateway, + "id": transaction.payment.token, + }, + ) return GatewayResponse( is_success=True, action_required=False, kind=TransactionKind.REFUND_ONGOING, - amount=payment_information.amount, - currency=payment_information.currency, + amount=amount, + currency=currency, transaction_id=result.message.get("pspReference", ""), error="", raw_response=result.message, diff --git a/saleor/payment/gateways/adyen/tests/test_plugin.py b/saleor/payment/gateways/adyen/tests/test_plugin.py index 2fc4ec9582c..6972902ac7d 100644 --- a/saleor/payment/gateways/adyen/tests/test_plugin.py +++ b/saleor/payment/gateways/adyen/tests/test_plugin.py @@ -10,6 +10,44 @@ from ....utils import create_payment_information, create_transaction +@mock.patch("saleor.payment.gateways.adyen.plugin.api_call") +def test_process_additional_action( + mocked_api_call, + dummy_payment_data, + payment_dummy, + checkout_ready_to_complete, + adyen_plugin, +): + expected_message = {"resultCode": "authorised", "pspReference": "ref-id"} + mocked_app_response = mock.MagicMock(message=expected_message) + + mocked_api_call.return_value = mocked_app_response + plugin = adyen_plugin(auto_capture=False) + dummy_payment_data.data = { + "additional-data": "payment-data", + } + + kind = TransactionKind.AUTH + response = plugin._process_additional_action(dummy_payment_data, kind) + + assert response == GatewayResponse( + is_success=True, + action_required=False, + action_required_data=None, + kind=kind, + amount=dummy_payment_data.amount, + currency=dummy_payment_data.currency, + transaction_id="ref-id", + error=None, + raw_response=expected_message, + searchable_key="ref-id", + payment_method_info=PaymentMethodInfo(), + ) + mocked_api_call.assert_called_with( + dummy_payment_data.data, plugin.adyen.checkout.payments_details + ) + + @pytest.mark.vcr def test_get_payment_gateway_for_checkout( adyen_plugin, checkout_with_single_item, address diff --git a/saleor/payment/gateways/adyen/tests/test_utils.py b/saleor/payment/gateways/adyen/tests/test_utils.py index c0eca801468..2766fb2ca91 100644 --- a/saleor/payment/gateways/adyen/tests/test_utils.py +++ b/saleor/payment/gateways/adyen/tests/test_utils.py @@ -31,13 +31,16 @@ def test_get_shopper_locale_value(country_code, shopper_locale, settings): assert result == shopper_locale -def test_append_klarna_data(dummy_payment_data, payment_dummy, checkout_with_item): +def test_append_klarna_data( + dummy_payment_data, payment_dummy, checkout_ready_to_complete +): # given - checkout_with_item.payments.add(payment_dummy) - line = checkout_with_item.lines.first() + checkout_ready_to_complete.payments.add(payment_dummy) + line = checkout_ready_to_complete.lines.first() payment_data = { "reference": "test", } + country_code = checkout_ready_to_complete.get_country() # when result = append_klarna_data(dummy_payment_data, payment_data) @@ -48,10 +51,9 @@ def test_append_klarna_data(dummy_payment_data, payment_dummy, checkout_with_ite ) assert result == { "reference": "test", - "shopperLocale": "en_US", + "shopperLocale": get_shopper_locale_value(country_code), "shopperReference": dummy_payment_data.customer_email, - "countryCode": str(checkout_with_item.country), - "shopperEmail": dummy_payment_data.customer_email, + "countryCode": country_code, "lineItems": [ { "description": f"{line.variant.product.name}, {line.variant.name}", @@ -61,14 +63,26 @@ def test_append_klarna_data(dummy_payment_data, payment_dummy, checkout_with_ite "taxPercentage": 0, "amountExcludingTax": total, "amountIncludingTax": total, - } + }, + { + "amountExcludingTax": "1000", + "amountIncludingTax": "1000", + "description": "Shipping - DHL", + "id": f"Shipping:{checkout_ready_to_complete.shipping_method.id}", + "quantity": 1, + "taxAmount": "0", + "taxPercentage": 0, + }, ], } @mock.patch("saleor.payment.gateways.adyen.utils.checkout_line_total") def test_append_klarna_data_tax_included( - mocked_checkout_line_total, dummy_payment_data, payment_dummy, checkout_with_item + mocked_checkout_line_total, + dummy_payment_data, + payment_dummy, + checkout_ready_to_complete, ): # given net = Money(100, "USD") @@ -77,9 +91,10 @@ def test_append_klarna_data_tax_included( mocked_checkout_line_total.return_value = quantize_price( TaxedMoney(net=net, gross=gross), "USD" ) + country_code = checkout_ready_to_complete.get_country() - checkout_with_item.payments.add(payment_dummy) - line = checkout_with_item.lines.first() + checkout_ready_to_complete.payments.add(payment_dummy) + line = checkout_ready_to_complete.lines.first() payment_data = { "reference": "test", } @@ -88,12 +103,12 @@ def test_append_klarna_data_tax_included( result = append_klarna_data(dummy_payment_data, payment_data) # then - assert result == { + + expected_result = { "reference": "test", - "shopperLocale": "en_US", + "shopperLocale": get_shopper_locale_value(country_code), "shopperReference": dummy_payment_data.customer_email, - "countryCode": str(checkout_with_item.country), - "shopperEmail": dummy_payment_data.customer_email, + "countryCode": country_code, "lineItems": [ { "description": f"{line.variant.product.name}, {line.variant.name}", @@ -103,14 +118,25 @@ def test_append_klarna_data_tax_included( "taxPercentage": 2300, "amountExcludingTax": to_adyen_price(net.amount, "USD"), "amountIncludingTax": to_adyen_price(gross.amount, "USD"), - } + }, + { + "amountExcludingTax": "1000", + "amountIncludingTax": "1000", + "description": "Shipping - DHL", + "id": f"Shipping:{checkout_ready_to_complete.shipping_method.id}", + "quantity": 1, + "taxAmount": "0", + "taxPercentage": 0, + }, ], } + assert result == expected_result def test_request_data_for_payment_payment_not_valid(dummy_payment_data): # given dummy_payment_data.data = { + "originUrl": "https://www.example.com", "is_valid": False, } native_3d_secure = False @@ -121,7 +147,6 @@ def test_request_data_for_payment_payment_not_valid(dummy_payment_data): dummy_payment_data, "https://www.example.com", "MerchantTestAccount", - "https://www.example.com", native_3d_secure, ) @@ -133,6 +158,7 @@ def test_request_data_for_payment(dummy_payment_data): # given return_url = "https://www.example.com" merchant_account = "MerchantTestAccount" + origin_url = "https://www.example.com" data = { "is_valid": True, "riskData": {"clientData": "test_client_data"}, @@ -140,13 +166,14 @@ def test_request_data_for_payment(dummy_payment_data): "browserInfo": {"acceptHeader": "*/*", "colorDepth": 30, "language": "pl"}, "billingAddress": {"address": "test_address"}, "shopperIP": "123", + "originUrl": origin_url, } dummy_payment_data.data = data native_3d_secure = False # when result = request_data_for_payment( - dummy_payment_data, return_url, merchant_account, return_url, native_3d_secure + dummy_payment_data, return_url, merchant_account, native_3d_secure ) # then @@ -166,6 +193,7 @@ def test_request_data_for_payment(dummy_payment_data): "billingAddress": data["billingAddress"], "browserInfo": data["browserInfo"], "channel": "web", + "shopperEmail": "example@test.com", } @@ -173,6 +201,7 @@ def test_request_data_for_payment_native_3d_secure(dummy_payment_data): # given return_url = "https://www.example.com" merchant_account = "MerchantTestAccount" + origin_url = "https://www.example.com" data = { "is_valid": True, "riskData": {"clientData": "test_client_data"}, @@ -180,13 +209,14 @@ def test_request_data_for_payment_native_3d_secure(dummy_payment_data): "browserInfo": {"acceptHeader": "*/*", "colorDepth": 30, "language": "pl"}, "billingAddress": {"address": "test_address"}, "shopperIP": "123", + "originUrl": origin_url, } dummy_payment_data.data = data native_3d_secure = True # when result = request_data_for_payment( - dummy_payment_data, return_url, merchant_account, return_url, native_3d_secure + dummy_payment_data, return_url, merchant_account, native_3d_secure ) # then @@ -201,12 +231,13 @@ def test_request_data_for_payment_native_3d_secure(dummy_payment_data): "paymentMethod": {"type": "scheme"}, "returnUrl": return_url, "merchantAccount": merchant_account, - "origin": return_url, + "origin": origin_url, "shopperIP": data["shopperIP"], "billingAddress": data["billingAddress"], "browserInfo": data["browserInfo"], "channel": "web", "additionalData": {"allow3DS2": "true"}, + "shopperEmail": "example@test.com", } @@ -220,7 +251,7 @@ def test_request_data_for_payment_channel_different_than_web(dummy_payment_data) # when result = request_data_for_payment( - dummy_payment_data, return_url, merchant_account, return_url, native_3d_secure + dummy_payment_data, return_url, merchant_account, native_3d_secure ) # then @@ -237,6 +268,7 @@ def test_request_data_for_payment_channel_different_than_web(dummy_payment_data) "merchantAccount": merchant_account, "channel": "iOS", "additionalData": {"allow3DS2": "true"}, + "shopperEmail": "example@test.com", } @@ -247,6 +279,7 @@ def test_request_data_for_payment_append_klarna_data( # given return_url = "https://www.example.com" merchant_account = "MerchantTestAccount" + origin_url = "https://www.example.com" data = { "is_valid": True, "riskData": {"clientData": "test_client_data"}, @@ -254,6 +287,7 @@ def test_request_data_for_payment_append_klarna_data( "browserInfo": {"acceptHeader": "*/*", "colorDepth": 30, "language": "pl"}, "billingAddress": {"address": "test_address"}, "shopperIP": "123", + "originUrl": origin_url, } dummy_payment_data.data = data klarna_result = { @@ -272,13 +306,12 @@ def test_request_data_for_payment_append_klarna_data( "billingAddress": data["billingAddress"], "browserInfo": data["browserInfo"], "shopperLocale": "test_shopper", - "shopperEmail": "test_email", } append_klarna_data_mock.return_value = klarna_result native_3d_secure = False # when result = request_data_for_payment( - dummy_payment_data, return_url, merchant_account, return_url, native_3d_secure + dummy_payment_data, return_url, merchant_account, native_3d_secure ) # then diff --git a/saleor/payment/gateways/adyen/tests/webhooks/test_get_payment.py b/saleor/payment/gateways/adyen/tests/webhooks/test_get_payment.py new file mode 100644 index 00000000000..915d50d50ad --- /dev/null +++ b/saleor/payment/gateways/adyen/tests/webhooks/test_get_payment.py @@ -0,0 +1,56 @@ +import logging + +import graphene +import pytest + +from ...webhooks import get_payment + +logger = logging.getLogger(__name__) + + +@pytest.mark.parametrize("payment_id", ["123", "Test payment ID"]) +def test_get_payment_invalid_payment_id(payment_id, caplog): + # given + caplog.set_level(logging.WARNING) + + # when + result = get_payment(payment_id) + + # then + assert result is None + assert f"Unable to decode the payment ID {payment_id}." in caplog.text + + +@pytest.mark.parametrize("payment_id", [" ", None]) +def test_get_payment_missing_payment_id(payment_id, caplog): + # given + caplog.set_level(logging.WARNING) + + # when + result = get_payment(payment_id) + + # then + assert result is None + assert "Missing payment ID." in caplog.text + + +def test_get_payment_not_active_payment(payment_dummy, caplog): + # given + caplog.set_level(logging.WARNING) + + payment_dummy.is_active = False + payment_dummy.save(update_fields=["is_active"]) + + payment_id = graphene.Node.to_global_id("Payemnt", payment_dummy.pk) + transaction_id = "psp reference" + + # when + result = get_payment(payment_id, transaction_id) + + # then + expected_msg = ( + f"Payment for {payment_id} ({payment_dummy.pk}) was not found. Reference " + f"{transaction_id}" + ) + assert not result + assert expected_msg in caplog.text diff --git a/saleor/payment/gateways/adyen/tests/webhooks/test_handle_additional_actions.py b/saleor/payment/gateways/adyen/tests/webhooks/test_handle_additional_actions.py index 449121f91d7..b5106e058f8 100644 --- a/saleor/payment/gateways/adyen/tests/webhooks/test_handle_additional_actions.py +++ b/saleor/payment/gateways/adyen/tests/webhooks/test_handle_additional_actions.py @@ -4,6 +4,7 @@ from urllib.parse import quote_plus import graphene +import pytest from ..... import PaymentError, TransactionKind from ...webhooks import handle_additional_actions @@ -61,6 +62,51 @@ def test_handle_additional_actions_post( assert payment_adyen_for_checkout.checkout is None +@pytest.mark.parametrize( + "custom_url", + [ + "adyencheckout://your.package.name", + "myiOSapp://path", + "https://checkout.saleor.com/", + ], +) +@mock.patch("saleor.payment.gateways.adyen.webhooks.api_call") +def test_handle_additional_actions_handles_return_urls( + api_call_mock, custom_url, payment_adyen_for_checkout, adyen_plugin +): + # given + adyen_plugin() + payment_adyen_for_checkout.return_url = custom_url + payment_adyen_for_checkout.to_confirm = True + payment_adyen_for_checkout.extra_data = json.dumps( + [{"payment_data": "test_data", "parameters": ["payload"]}] + ) + payment_adyen_for_checkout.save( + update_fields=["to_confirm", "extra_data", "return_url"] + ) + + checkout = payment_adyen_for_checkout.checkout + payment_id = graphene.Node.to_global_id("Payment", payment_adyen_for_checkout.pk) + + request_mock = mock.Mock() + request_mock.GET = {"payment": payment_id, "checkout": str(checkout.pk)} + request_mock.POST = {"payload": "test"} + + payment_details_mock = mock.Mock() + message = { + "pspReference": "11111", + "resultCode": "Test", + } + api_call_mock.return_value.message = message + + # when + response = handle_additional_actions(request_mock, payment_details_mock) + + # then + payment_adyen_for_checkout.refresh_from_db() + assert response.status_code == 302 + + @mock.patch("saleor.payment.gateways.adyen.webhooks.api_call") def test_handle_additional_actions_get( api_call_mock, payment_adyen_for_checkout, adyen_plugin diff --git a/saleor/payment/gateways/adyen/tests/webhooks/test_handle_notifications.py b/saleor/payment/gateways/adyen/tests/webhooks/test_handle_notifications.py index 38135a2dd0a..4ef9266013c 100644 --- a/saleor/payment/gateways/adyen/tests/webhooks/test_handle_notifications.py +++ b/saleor/payment/gateways/adyen/tests/webhooks/test_handle_notifications.py @@ -1,3 +1,4 @@ +import logging from decimal import Decimal from unittest import mock @@ -22,6 +23,8 @@ webhook_not_implemented, ) +logger = logging.getLogger(__name__) + def test_handle_authorization_for_order( notification, adyen_plugin, payment_adyen_for_order @@ -45,6 +48,27 @@ def test_handle_authorization_for_order( assert external_events.count() == 1 +def test_handle_authorization_for_order_invalid_payment_id( + notification, adyen_plugin, payment_adyen_for_order, caplog +): + payment = payment_adyen_for_order + invalid_reference = "test invalid reference" + notification = notification( + merchant_reference=invalid_reference, + value=to_adyen_price(payment.total, payment.currency), + ) + config = adyen_plugin().config + transaction_count = payment.transactions.count() + + caplog.set_level(logging.WARNING) + + handle_authorization(notification, config) + + payment.refresh_from_db() + assert payment.transactions.count() == transaction_count + assert f"Unable to decode the payment ID {invalid_reference}." in caplog.text + + def test_handle_multiple_authorization_notification( notification, adyen_plugin, payment_adyen_for_order ): @@ -248,9 +272,14 @@ def test_handle_authorization_with_adyen_auto_capture_and_payment_charged( assert external_events.count() == 1 -def test_handle_cancel(notification, adyen_plugin, payment_adyen_for_order): +@pytest.mark.parametrize("payment_is_active", (True, False)) +def test_handle_cancel( + payment_is_active, notification, adyen_plugin, payment_adyen_for_order +): payment = payment_adyen_for_order payment.charge_status = ChargeStatus.FULLY_CHARGED + payment.is_active = payment_is_active + payment.save() payment_id = graphene.Node.to_global_id("Payment", payment.pk) notification = notification( merchant_reference=payment_id, @@ -272,6 +301,31 @@ def test_handle_cancel(notification, adyen_plugin, payment_adyen_for_order): assert external_events.count() == 1 +def test_handle_cancel_invalid_payment_id( + notification, adyen_plugin, payment_adyen_for_order, caplog +): + payment = payment_adyen_for_order + payment.charge_status = ChargeStatus.FULLY_CHARGED + invalid_reference = "test invalid reference" + notification = notification( + merchant_reference=invalid_reference, + value=to_adyen_price(payment.total, payment.currency), + ) + config = adyen_plugin().config + transaction_count = payment.transactions.count() + + caplog.set_level(logging.WARNING) + + handle_cancellation(notification, config) + + payment.order.refresh_from_db() + assert payment.transactions.count() == transaction_count + + payment.refresh_from_db() + assert payment.transactions.count() == transaction_count + assert f"Unable to decode the payment ID {invalid_reference}." in caplog.text + + def test_handle_cancel_already_canceled( notification, adyen_plugin, payment_adyen_for_order ): @@ -354,6 +408,27 @@ def test_handle_capture_for_checkout( assert external_events.count() == 1 +def test_handle_capture_invalid_payment_id( + notification, adyen_plugin, payment_adyen_for_order, caplog +): + payment = payment_adyen_for_order + invalid_reference = "test invalid reference" + notification = notification( + merchant_reference=invalid_reference, + value=to_adyen_price(payment.total, payment.currency), + ) + config = adyen_plugin().config + transaction_count = payment.transactions.count() + + caplog.set_level(logging.WARNING) + + handle_capture(notification, config) + + payment.refresh_from_db() + assert payment.transactions.count() == transaction_count + assert f"Unable to decode the payment ID {invalid_reference}." in caplog.text + + def test_handle_capture_with_payment_already_charged( notification, adyen_plugin, payment_adyen_for_order ): @@ -409,6 +484,30 @@ def test_handle_failed_capture( assert external_events.count() == 1 +def test_handle_failed_capture_invalid_payment_id( + notification, adyen_plugin, payment_adyen_for_order, caplog +): + payment = payment_adyen_for_order + payment.charge_status = ChargeStatus.FULLY_CHARGED + payment.captured_amount = payment.total + payment.save() + invalid_reference = "test invalid reference" + notification = notification( + merchant_reference=invalid_reference, + value=to_adyen_price(payment.total, payment.currency), + ) + config = adyen_plugin().config + transaction_count = payment.transactions.count() + + caplog.set_level(logging.WARNING) + + handle_failed_capture(notification, config) + + payment.refresh_from_db() + assert payment.transactions.count() == transaction_count + assert f"Unable to decode the payment ID {invalid_reference}." in caplog.text + + def test_handle_failed_capture_partial_charge( notification, adyen_plugin, payment_adyen_for_order ): @@ -458,6 +557,27 @@ def test_handle_pending(notification, adyen_plugin, payment_adyen_for_order): assert external_events.count() == 1 +def test_handle_pending_invalid_payment_id( + notification, adyen_plugin, payment_adyen_for_order, caplog +): + payment = payment_adyen_for_order + invalid_reference = "test invalid reference" + notification = notification( + merchant_reference=invalid_reference, + value=to_adyen_price(payment.total, payment.currency), + ) + config = adyen_plugin().config + transaction_count = payment.transactions.count() + + caplog.set_level(logging.WARNING) + + handle_pending(notification, config) + + payment.refresh_from_db() + assert payment.transactions.count() == transaction_count + assert f"Unable to decode the payment ID {invalid_reference}." in caplog.text + + def test_handle_pending_with_adyen_auto_capture( notification, adyen_plugin, payment_adyen_for_order ): @@ -535,6 +655,30 @@ def test_handle_refund( assert external_events.count() == 1 +def test_handle_refund_invalid_payment_id( + notification, adyen_plugin, payment_adyen_for_order, caplog +): + payment = payment_adyen_for_order + payment.charge_status = ChargeStatus.FULLY_CHARGED + payment.captured_amount = payment.total + payment.save() + invalid_reference = "test invalid reference" + notification = notification( + merchant_reference=invalid_reference, + value=to_adyen_price(payment.total, payment.currency), + ) + config = adyen_plugin().config + transaction_count = payment.transactions.count() + + caplog.set_level(logging.WARNING) + + handle_refund(notification, config) + + payment.refresh_from_db() + assert payment.transactions.count() == transaction_count + assert f"Unable to decode the payment ID {invalid_reference}." in caplog.text + + @mock.patch("saleor.payment.gateways.adyen.webhooks.order_refunded") def test_handle_refund_already_refunded( mock_order_refunded, notification, adyen_plugin, payment_adyen_for_order @@ -580,6 +724,30 @@ def test_handle_failed_refund_missing_transaction( assert external_events.count() == 1 +def test_handle_failed_refund_invalid_payment_id( + notification, adyen_plugin, payment_adyen_for_order, caplog +): + payment = payment_adyen_for_order + payment.charge_status = ChargeStatus.FULLY_CHARGED + payment.captured_amount = payment.total + payment.save() + invalid_reference = "test invalid reference" + notification = notification( + merchant_reference=invalid_reference, + value=to_adyen_price(payment.total, payment.currency), + ) + config = adyen_plugin().config + transaction_count = payment.transactions.count() + + caplog.set_level(logging.WARNING) + + handle_failed_refund(notification, config) + + payment.refresh_from_db() + assert payment.transactions.count() == transaction_count + assert f"Unable to decode the payment ID {invalid_reference}." in caplog.text + + def test_handle_failed_refund_with_transaction_refund_ongoing( notification, adyen_plugin, payment_adyen_for_order ): @@ -655,6 +823,30 @@ def test_handle_reversed_refund(notification, adyen_plugin, payment_adyen_for_or assert external_events.count() == 1 +def test_handle_reversed_refund_invalid_payment_id( + notification, adyen_plugin, payment_adyen_for_order, caplog +): + payment = payment_adyen_for_order + payment.charge_status = ChargeStatus.FULLY_REFUNDED + payment.captured_amount = Decimal("0.0") + payment.save() + invalid_reference = "test invalid reference" + notification = notification( + merchant_reference=invalid_reference, + value=to_adyen_price(payment.total, payment.currency), + ) + config = adyen_plugin().config + transaction_count = payment.transactions.count() + + caplog.set_level(logging.WARNING) + + handle_reversed_refund(notification, config) + + payment.refresh_from_db() + assert payment.transactions.count() == transaction_count + assert f"Unable to decode the payment ID {invalid_reference}." in caplog.text + + def test_handle_reversed_refund_already_processed( notification, adyen_plugin, payment_adyen_for_order ): @@ -694,6 +886,30 @@ def test_webhook_not_implemented(notification, adyen_plugin, payment_adyen_for_o assert external_events.count() == 1 +def test_webhook_not_implemented_invalid_payment_id( + notification, adyen_plugin, payment_adyen_for_order, caplog +): + payment = payment_adyen_for_order + payment.charge_status = ChargeStatus.FULLY_CHARGED + payment.captured_amount = payment.total + payment.save() + invalid_reference = "test invalid reference" + notification = notification( + merchant_reference=invalid_reference, + value=to_adyen_price(payment.total, payment.currency), + ) + config = adyen_plugin().config + transaction_count = payment.transactions.count() + + caplog.set_level(logging.WARNING) + + webhook_not_implemented(notification, config) + + payment.refresh_from_db() + assert payment.transactions.count() == transaction_count + assert f"Unable to decode the payment ID {invalid_reference}." in caplog.text + + @mock.patch("saleor.payment.gateways.adyen.webhooks.handle_refund") def test_handle_cancel_or_refund_action_refund( mock_handle_refund, notification, adyen_plugin, payment_adyen_for_order @@ -729,3 +945,22 @@ def test_handle_cancel_or_refund_action_cancel( handle_cancel_or_refund(notification, config) mock_handle_cancellation.assert_called_once_with(notification, config) + + +def test_handle_cancel_or_refund_action_cancel_invalid_payment_id( + notification, adyen_plugin, payment_adyen_for_order, caplog +): + payment = payment_adyen_for_order + config = adyen_plugin().config + invalid_reference = "test invalid reference" + notification = notification( + merchant_reference=invalid_reference, + value=to_adyen_price(payment.total, payment.currency), + ) + notification["additionalData"]["modification.action"] = "cancel" + + caplog.set_level(logging.WARNING) + + handle_cancel_or_refund(notification, config) + + assert f"Unable to decode the payment ID {invalid_reference}." in caplog.text diff --git a/saleor/payment/gateways/adyen/tests/webhooks/test_validate_notification.py b/saleor/payment/gateways/adyen/tests/webhooks/test_validate_notification.py index 942087f5a46..339f1afb206 100644 --- a/saleor/payment/gateways/adyen/tests/webhooks/test_validate_notification.py +++ b/saleor/payment/gateways/adyen/tests/webhooks/test_validate_notification.py @@ -1,6 +1,10 @@ from django.contrib.auth.hashers import make_password -from ...webhooks import validate_auth_user, validate_hmac_signature +from ...webhooks import ( + validate_auth_user, + validate_hmac_signature, + validate_merchant_account, +) def test_validate_hmac_signature(adyen_plugin, notification_with_hmac_signature): @@ -73,3 +77,21 @@ def test_validate_auth_user_when_auth_is_disabled(adyen_plugin): config = plugin.config is_valid = validate_auth_user(headers={}, gateway_config=config) assert is_valid is True + + +def test_validate_merchant_account(adyen_plugin, notification_with_hmac_signature): + plugin = adyen_plugin() + config = plugin.config + notification_with_hmac_signature[ + "merchantAccountCode" + ] = config.connection_params.get("merchant_account") + assert validate_merchant_account(notification_with_hmac_signature, config) is True + + +def test_validate_merchant_account_invalid_merchant_account( + adyen_plugin, notification_with_hmac_signature +): + plugin = adyen_plugin() + config = plugin.config + notification_with_hmac_signature["merchantAccountCode"] = "test" + assert validate_merchant_account(notification_with_hmac_signature, config) is False diff --git a/saleor/payment/gateways/adyen/utils.py b/saleor/payment/gateways/adyen/utils.py index 21b5718f998..599d6aebc16 100644 --- a/saleor/payment/gateways/adyen/utils.py +++ b/saleor/payment/gateways/adyen/utils.py @@ -8,7 +8,11 @@ from django.conf import settings from django_countries.fields import Country -from ....checkout.calculations import checkout_line_total, checkout_total +from ....checkout.calculations import ( + checkout_line_total, + checkout_shipping_price, + checkout_total, +) from ....checkout.models import Checkout from ....core.prices import quantize_price from ....discount.utils import fetch_active_discounts @@ -45,6 +49,17 @@ def to_adyen_price(value: Decimal, currency: str): return str(value_without_comma.quantize(Decimal("1"))) +def get_tax_percentage_in_adyen_format(total_gross, total_net): + tax_percentage_in_adyen_format = 0 + if total_gross and total_net: + # get tax percent in adyen format + gross_percentage = total_gross / total_net + gross_percentage = gross_percentage.quantize(Decimal(".01")) # 1.23 + tax_percentage = gross_percentage * 100 - 100 # 23.00 + tax_percentage_in_adyen_format = int(tax_percentage * 100) # 2300 + return tax_percentage_in_adyen_format + + def api_call(request_data: Optional[Dict[str, Any]], method: Callable) -> Adyen.Adyen: try: return method(request_data) @@ -57,7 +72,6 @@ def request_data_for_payment( payment_information: "PaymentData", return_url: str, merchant_account: str, - origin_url: str, native_3d_secure: bool, ) -> Dict[str, Any]: payment_data = payment_information.data or {} @@ -67,24 +81,46 @@ def request_data_for_payment( extra_request_params = {} channel = payment_data.get("channel", "web") - if "browserInfo" in payment_data: - extra_request_params["browserInfo"] = payment_data["browserInfo"] - if "billingAddress" in payment_data: - extra_request_params["billingAddress"] = payment_data["billingAddress"] - if "shopperIP" in payment_data: - extra_request_params["shopperIP"] = payment_data["shopperIP"] + origin_url = payment_data.get("originUrl") + + browser_info = payment_data.get("browserInfo") + if browser_info: + extra_request_params["browserInfo"] = browser_info + + billing_address = payment_data.get("billingAddress") + if billing_address: + extra_request_params["billingAddress"] = billing_address + + delivery_address = payment_data.get("deliveryAddress") + if delivery_address: + extra_request_params["deliveryAddress"] = delivery_address + + shopper_ip = payment_data.get("shopperIP") + if shopper_ip: + extra_request_params["shopperIP"] = shopper_ip + + device_fingerprint = payment_data.get("deviceFingerprint") + if device_fingerprint: + extra_request_params["deviceFingerprint"] = device_fingerprint if channel.lower() == "web" and origin_url: extra_request_params["origin"] = origin_url + shopper_name = payment_data.get("shopperName") + if shopper_name: + extra_request_params["shopperName"] = shopper_name + extra_request_params["channel"] = channel - if native_3d_secure: - extra_request_params["additionalData"] = {"allow3DS2": "true"} payment_method = payment_data.get("paymentMethod") if not payment_method: raise PaymentError("Unable to find the paymentMethod section.") + method = payment_method.get("type", "") + if native_3d_secure and "scheme" == method: + extra_request_params["additionalData"] = {"allow3DS2": "true"} + + extra_request_params["shopperEmail"] = payment_information.customer_email request_data = { "amount": { "value": to_adyen_price( @@ -99,21 +135,43 @@ def request_data_for_payment( **extra_request_params, } - method = payment_method.get("type", []) if "klarna" in method: request_data = append_klarna_data(payment_information, request_data) return request_data +def get_shipping_data(checkout, lines, discounts): + shipping_total = checkout_shipping_price( + checkout=checkout, lines=lines, discounts=discounts + ) + total_gross = shipping_total.gross.amount + total_net = shipping_total.net.amount + tax_amount = shipping_total.tax.amount + tax_percentage_in_adyen_format = get_tax_percentage_in_adyen_format( + total_gross, total_net + ) + return { + "quantity": 1, + "amountExcludingTax": to_adyen_price(total_net, checkout.currency), + "taxPercentage": tax_percentage_in_adyen_format, + "description": f"Shipping - {checkout.shipping_method.name}", + "id": f"Shipping:{checkout.shipping_method.id}", + "taxAmount": to_adyen_price(tax_amount, checkout.currency), + "amountIncludingTax": to_adyen_price(total_gross, checkout.currency), + } + + def append_klarna_data(payment_information: "PaymentData", payment_data: dict): - checkout = Checkout.objects.filter( - payments__id=payment_information.payment_id - ).first() + checkout = ( + Checkout.objects.prefetch_related("shipping_method",) + .filter(payments__id=payment_information.payment_id) + .first() + ) if not checkout: raise PaymentError("Unable to calculate products for klarna.") - lines = checkout.lines.prefetch_related("variant").all() + lines = checkout.lines.prefetch_related("variant__product").all() discounts = fetch_active_discounts() currency = payment_information.currency country_code = checkout.get_country() @@ -121,21 +179,16 @@ def append_klarna_data(payment_information: "PaymentData", payment_data: dict): payment_data["shopperLocale"] = get_shopper_locale_value(country_code) payment_data["shopperReference"] = payment_information.customer_email payment_data["countryCode"] = country_code - payment_data["shopperEmail"] = payment_information.customer_email line_items = [] + for line in lines: total = checkout_line_total(line=line, discounts=discounts) total_gross = total.gross.amount total_net = total.net.amount tax_amount = total.tax.amount - - tax_percentage_in_adyen_format = 0 - if total_gross: - # get tax percent in adyen format - gross_percentage = total_gross / total_net - gross_percentage = gross_percentage.quantize(Decimal(".01")) # 1.23 - tax_percentage = gross_percentage * 100 - 100 # 23.00 - tax_percentage_in_adyen_format = int(tax_percentage * 100) # 2300 + tax_percentage_in_adyen_format = get_tax_percentage_in_adyen_format( + total_gross, total_net + ) line_data = { "quantity": line.quantity, @@ -147,6 +200,10 @@ def append_klarna_data(payment_information: "PaymentData", payment_data: dict): "amountIncludingTax": to_adyen_price(total_gross, currency), } line_items.append(line_data) + + if checkout.shipping_method and checkout.is_shipping_required(): + line_items.append(get_shipping_data(checkout, lines, discounts)) + payment_data["lineItems"] = line_items return payment_data diff --git a/saleor/payment/gateways/adyen/webhooks.py b/saleor/payment/gateways/adyen/webhooks.py index 5a2e226bbc8..0732cfbe4c5 100644 --- a/saleor/payment/gateways/adyen/webhooks.py +++ b/saleor/payment/gateways/adyen/webhooks.py @@ -4,8 +4,9 @@ import hmac import json import logging +from json.decoder import JSONDecodeError from typing import Any, Callable, Dict, Optional -from urllib.parse import urlencode +from urllib.parse import urlencode, urlparse import Adyen import graphene @@ -20,7 +21,7 @@ QueryDict, ) from django.http.request import HttpHeaders -from django.shortcuts import redirect +from django.http.response import HttpResponseRedirect from graphql_relay import from_global_id from ....checkout.complete_checkout import complete_checkout @@ -46,30 +47,37 @@ def get_payment( - payment_id: Optional[str], transaction_id: Optional[str] = None + payment_id: Optional[str], + transaction_id: Optional[str] = None, + check_if_active=True, ) -> Optional[Payment]: transaction_id = transaction_id or "" - if not payment_id: + if payment_id is None or not payment_id.strip(): logger.warning("Missing payment ID. Reference %s", transaction_id) return None try: _type, db_payment_id = from_global_id(payment_id) - except UnicodeDecodeError: + except (UnicodeDecodeError, binascii.Error): logger.warning( "Unable to decode the payment ID %s. Reference %s", payment_id, transaction_id, ) return None - payment = ( + payments = ( Payment.objects.prefetch_related("order", "checkout") .select_for_update(of=("self",)) - .filter(id=db_payment_id, is_active=True, gateway="mirumee.payments.adyen") - .first() + .filter(id=db_payment_id, gateway="mirumee.payments.adyen") ) + if check_if_active: + payments = payments.filter(is_active=True) + payment = payments.first() if not payment: logger.warning( - "Payment for %s was not found. Reference %s", payment_id, transaction_id + "Payment for %s (%s) was not found. Reference %s", + payment_id, + db_payment_id, + transaction_id, ) return payment @@ -154,7 +162,7 @@ def create_order(payment, checkout): return order -def handle_not_created_order(notification, payment, checkout): +def handle_not_created_order(notification, payment, checkout, kind): """Process the notification in case when payment doesn't have assigned order.""" # We don't want to create order for payment that is cancelled or refunded @@ -165,14 +173,18 @@ def handle_not_created_order(notification, payment, checkout): ChargeStatus.FULLY_CHARGED, }: return - # If the payment is not Auth/Capture, it means that user didn't return to the - # storefront and we need to finalize the checkout asynchronously. - action_transaction = create_new_transaction( - notification, payment, TransactionKind.ACTION_TO_CONFIRM - ) + transaction = payment.transactions.filter( + action_required=False, is_success=True, kind=kind + ).last() + if not transaction: + # If the payment is not Auth/Capture, it means that user didn't return to the + # storefront and we need to finalize the checkout asynchronously. + transaction = create_new_transaction( + notification, payment, TransactionKind.ACTION_TO_CONFIRM + ) # Only when we confirm that notification is success we will create the order - if action_transaction.is_success and checkout: # type: ignore + if transaction.is_success and checkout: # type: ignore order = create_order(payment, checkout) return order return None @@ -186,8 +198,12 @@ def handle_authorization(notification: Dict[str, Any], gateway_config: GatewayCo return checkout = get_checkout(payment) + adyen_auto_capture = gateway_config.connection_params["adyen_auto_capture"] + kind = TransactionKind.AUTH + if adyen_auto_capture: + kind = TransactionKind.CAPTURE if not payment.order: - handle_not_created_order(notification, payment, checkout) + handle_not_created_order(notification, payment, checkout, kind) else: adyen_auto_capture = gateway_config.connection_params["adyen_auto_capture"] kind = TransactionKind.AUTH @@ -199,13 +215,16 @@ def handle_authorization(notification: Dict[str, Any], gateway_config: GatewayCo is_success=True, kind__in=[TransactionKind.AUTH, TransactionKind.CAPTURE], ).last() - new_transaction = create_new_transaction(notification, payment, kind) - if new_transaction.is_success and not transaction: - gateway_postprocess(new_transaction, payment) - if adyen_auto_capture: - order_captured(payment.order, None, new_transaction.amount, payment) - else: - order_authorized(payment.order, None, new_transaction.amount, payment) + if not transaction: + new_transaction = create_new_transaction(notification, payment, kind) + if new_transaction.is_success: + gateway_postprocess(new_transaction, payment) + if adyen_auto_capture: + order_captured(payment.order, None, new_transaction.amount, payment) + else: + order_authorized( + payment.order, None, new_transaction.amount, payment + ) reason = notification.get("reason", "-") is_success = True if notification.get("success") == "true" else False success_msg = f"Adyen: The payment {transaction_id} request was successful." @@ -218,7 +237,12 @@ def handle_authorization(notification: Dict[str, Any], gateway_config: GatewayCo def handle_cancellation(notification: Dict[str, Any], _gateway_config: GatewayConfig): # https://docs.adyen.com/checkout/cancel#cancellation-notifciation transaction_id = notification.get("pspReference") - payment = get_payment(notification.get("merchantReference"), transaction_id) + payment = get_payment( + # check_if_active=False as the payment can be still active or already cancelled + notification.get("merchantReference"), + transaction_id, + check_if_active=False, + ) if not payment: return transaction = get_transaction(payment, transaction_id, TransactionKind.CANCEL) @@ -263,7 +287,9 @@ def handle_capture(notification: Dict[str, Any], _gateway_config: GatewayConfig) checkout = get_checkout(payment) if not payment.order: - handle_not_created_order(notification, payment, checkout) + handle_not_created_order( + notification, payment, checkout, TransactionKind.CAPTURE + ) else: capture_transaction = payment.transactions.filter( action_required=False, is_success=True, kind=TransactionKind.CAPTURE, @@ -569,15 +595,31 @@ def validate_auth_user(headers: HttpHeaders, gateway_config: "GatewayConfig") -> return False +def validate_merchant_account( + notification: Dict[str, Any], gateway_config: "GatewayConfig" +): + merchant_account_code = notification.get("merchantAccountCode") + return merchant_account_code == gateway_config.connection_params.get( + "merchant_account" + ) + + @transaction_with_commit_on_errors() def handle_webhook(request: WSGIRequest, gateway_config: "GatewayConfig"): - json_data = json.loads(request.body) + try: + json_data = json.loads(request.body) + except JSONDecodeError: + logger.warning("Cannot parse request body.") + return HttpResponse("[accepted]") # JSON and HTTP POST notifications always contain a single NotificationRequestItem # object. notification = json_data.get("notificationItems")[0].get( "NotificationRequestItem", {} ) + if not validate_merchant_account(notification, gateway_config): + logger.warning("Not supported merchant account.") + return HttpResponse("[accepted]") if not validate_hmac_signature(notification, gateway_config): return HttpResponseBadRequest("Invalid or missing hmac signature.") if not validate_auth_user(request.headers, gateway_config): @@ -628,11 +670,12 @@ def handle_additional_actions( result = api_call(request_data, payment_details) except PaymentError as e: return HttpResponseBadRequest(str(e)) - handle_api_response(payment, result) - redirect_url = prepare_redirect_url(payment_id, checkout_pk, result, return_url) - return redirect(redirect_url) + parsed = urlparse(return_url) + redirect_class = HttpResponseRedirect + redirect_class.allowed_schemes = [parsed.scheme] + return redirect_class(redirect_url) def prepare_api_request_data(request: WSGIRequest, data: dict): @@ -722,6 +765,5 @@ def handle_api_response( payment_information=payment_data, gateway_response=gateway_response, ) - - if is_success and not action_required: + if is_success and not action_required and not payment.order: create_order(payment, checkout) diff --git a/saleor/plugins/base_plugin.py b/saleor/plugins/base_plugin.py index 3d63d9d66d9..be73b65918c 100644 --- a/saleor/plugins/base_plugin.py +++ b/saleor/plugins/base_plugin.py @@ -515,21 +515,28 @@ def _append_config_structure(cls, configuration: PluginConfigurationType): @classmethod def _update_configuration_structure(cls, configuration: PluginConfigurationType): + updated_configuration = [] config_structure = getattr(cls, "CONFIG_STRUCTURE") or {} desired_config_keys = set(config_structure.keys()) + for config_field in configuration: + if config_field["name"] not in desired_config_keys: + continue + updated_configuration.append(config_field) - configured_keys = set(d["name"] for d in configuration) + configured_keys = set(d["name"] for d in updated_configuration) missing_keys = desired_config_keys - configured_keys if not missing_keys: - return + return updated_configuration default_config = cls.DEFAULT_CONFIGURATION if not default_config: - return + return updated_configuration update_values = [copy(k) for k in default_config if k["name"] in missing_keys] - configuration.extend(update_values) + if update_values: + updated_configuration.extend(update_values) + return updated_configuration @classmethod def get_default_active(cls): @@ -540,7 +547,7 @@ def get_plugin_configuration( ) -> PluginConfigurationType: if not configuration: configuration = [] - self._update_configuration_structure(configuration) + configuration = self._update_configuration_structure(configuration) if configuration: # Let's add a translated descriptions and labels self._append_config_structure(configuration) diff --git a/saleor/plugins/manager.py b/saleor/plugins/manager.py index a06087bf8e4..171c2d617ee 100644 --- a/saleor/plugins/manager.py +++ b/saleor/plugins/manager.py @@ -485,9 +485,12 @@ def save_plugin_configuration(self, plugin_id, cleaned_data: dict): identifier=plugin_id, defaults={"configuration": plugin.configuration}, ) - return plugin.save_plugin_configuration( + configuration = plugin.save_plugin_configuration( plugin_configuration, cleaned_data ) + configuration.name = plugin.PLUGIN_NAME + configuration.description = plugin.PLUGIN_DESCRIPTION + return configuration def get_plugin(self, plugin_id: str) -> Optional["BasePlugin"]: for plugin in self.plugins: diff --git a/saleor/plugins/tests/test_plugins.py b/saleor/plugins/tests/test_plugins.py index c32ab9e77b3..67d89a7ac8e 100644 --- a/saleor/plugins/tests/test_plugins.py +++ b/saleor/plugins/tests/test_plugins.py @@ -78,6 +78,21 @@ def test_update_config_items_adds_new_keys(monkeypatch): assert any([config_field["name"] == "New-field" for config_field in current_config]) +def test_update_configuration_structure_removes_old_keys( + monkeypatch, plugin_configuration +): + mocked_config = { + name: value + for name, value in PluginSample.CONFIG_STRUCTURE.items() + if name != "Username" + } + monkeypatch.setattr(PluginSample, "CONFIG_STRUCTURE", mocked_config) + configuration = PluginSample._update_configuration_structure( + plugin_configuration.configuration + ) + assert all([config_field["name"] != "Username" for config_field in configuration]) + + def test_save_plugin_configuration(plugin_configuration): cleaned_data = {"configuration": [{"name": "Username", "value": "new-username"}]} PluginSample.save_plugin_configuration(plugin_configuration, cleaned_data) @@ -130,7 +145,9 @@ def test_base_plugin__update_configuration_structure_when_old_config_is_empty( ): plugin_configuration.configuration = [] plugin_configuration.save() - PluginSample._update_configuration_structure(plugin_configuration.configuration) + plugin_configuration.configuration = PluginSample._update_configuration_structure( + plugin_configuration.configuration + ) plugin_configuration.save() plugin_configuration.refresh_from_db() assert len(plugin_configuration.configuration) == len( @@ -154,7 +171,9 @@ def test_base_plugin__update_configuration_structure_configuration_has_change( "DEFAULT_CONFIGURATION", PluginSample.DEFAULT_CONFIGURATION + [private_key_dict], ) - PluginSample._update_configuration_structure(plugin_configuration.configuration) + plugin_configuration.configuration = PluginSample._update_configuration_structure( + plugin_configuration.configuration + ) plugin_configuration.save() plugin_configuration.refresh_from_db() assert len(old_configuration) + 1 == len(plugin_configuration.configuration) diff --git a/saleor/settings.py b/saleor/settings.py index afd42fe47c0..9f5f445645f 100644 --- a/saleor/settings.py +++ b/saleor/settings.py @@ -94,6 +94,7 @@ def get_bool_from_env(name, default_value): ("is", "Icelandic"), ("it", "Italian"), ("ja", "Japanese"), + ("ka", "Georgian"), ("km", "Khmer"), ("ko", "Korean"), ("lt", "Lithuanian"), diff --git a/saleor/tests/fixtures.py b/saleor/tests/fixtures.py index df056518367..6e252de3c60 100644 --- a/saleor/tests/fixtures.py +++ b/saleor/tests/fixtures.py @@ -1312,7 +1312,7 @@ def order_line_with_one_allocation(customer_user, variant_with_many_stocks): quantity=2, variant=variant, unit_price=TaxedMoney(net=net, gross=gross), - tax_rate=23, + tax_rate=Decimal(23), ) Allocation.objects.create( diff --git a/saleor/webhook/payloads.py b/saleor/webhook/payloads.py index 0a94adfee4a..85f5d02532b 100644 --- a/saleor/webhook/payloads.py +++ b/saleor/webhook/payloads.py @@ -1,5 +1,5 @@ import json -from typing import Optional +from typing import Iterable, Optional from django.db.models import QuerySet @@ -12,7 +12,7 @@ ) from ..invoice.models import Invoice from ..order import FulfillmentStatus, OrderStatus -from ..order.models import Fulfillment, FulfillmentLine, Order +from ..order.models import Fulfillment, FulfillmentLine, Order, OrderLine from ..order.utils import get_order_country from ..payment import ChargeStatus from ..product.models import Product @@ -55,6 +55,30 @@ ) +def generate_order_lines_payload(lines: Iterable[OrderLine]): + line_fields = ( + "product_name", + "variant_name", + "translated_product_name", + "translated_variant_name", + "product_sku", + "quantity", + "currency", + "unit_price_net_amount", + "unit_price_gross_amount", + "tax_rate", + ) + serializer = PayloadSerializer() + return serializer.serialize( + lines, + fields=line_fields, + extra_dict_data={ + "total_price_net_amount": (lambda l: l.get_total().net.amount), + "total_price_gross_amount": (lambda l: l.get_total().gross.amount), + }, + ) + + def generate_order_payload(order: "Order"): serializer = PayloadSerializer() fulfillment_fields = ("status", "tracking_number", "created") @@ -81,30 +105,20 @@ def generate_order_payload(order: "Order"): "billing_country_code", "billing_country_area", ) - line_fields = ( - "product_name", - "variant_name", - "translated_product_name", - "translated_variant_name", - "product_sku", - "quantity", - "currency", - "unit_price_net_amount", - "unit_price_gross_amount", - "tax_rate", - ) + shipping_method_fields = ("name", "type", "currency", "price_amount") + lines = order.lines.all() order_data = serializer.serialize( [order], fields=ORDER_FIELDS, additional_fields={ "shipping_method": (lambda o: o.shipping_method, shipping_method_fields), - "lines": (lambda o: o.lines.all(), line_fields), "payments": (lambda o: o.payments.all(), payment_fields), "shipping_address": (lambda o: o.shipping_address, ADDRESS_FIELDS), "billing_address": (lambda o: o.billing_address, ADDRESS_FIELDS), "fulfillments": (lambda o: o.fulfillments.all(), fulfillment_fields), }, + extra_dict_data={"lines": json.loads(generate_order_lines_payload(lines))}, ) return order_data diff --git a/saleor/webhook/tests/test_webhook_payloads.py b/saleor/webhook/tests/test_webhook_payloads.py index 9f0bb540039..0ce862d58e8 100644 --- a/saleor/webhook/tests/test_webhook_payloads.py +++ b/saleor/webhook/tests/test_webhook_payloads.py @@ -1,4 +1,5 @@ import json +from decimal import Decimal import graphene @@ -24,3 +25,35 @@ def test_generate_order_payload( assert payload.get("shipping_address") assert payload.get("billing_address") assert payload.get("fulfillments") + + +def test_order_lines_have_all_required_fields(order, order_line_with_one_allocation): + order.lines.add(order_line_with_one_allocation) + line = order_line_with_one_allocation + payload = json.loads(generate_order_payload(order))[0] + lines_payload = payload.get("lines") + + assert len(lines_payload) == 1 + line_id = graphene.Node.to_global_id("OrderLine", line.id) + line_payload = lines_payload[0] + unit_net_amount = line.unit_price_net_amount.quantize(Decimal("0.001")) + unit_gross_amount = line.unit_price_gross_amount.quantize(Decimal("0.001")) + total_line = line.get_total() + assert line_payload == { + "id": line_id, + "type": "OrderLine", + "product_name": line.product_name, + "variant_name": line.variant_name, + "translated_product_name": line.translated_product_name, + "translated_variant_name": line.translated_variant_name, + "product_sku": line.product_sku, + "quantity": line.quantity, + "currency": line.currency, + "unit_price_net_amount": str(unit_net_amount), + "unit_price_gross_amount": str(unit_gross_amount), + "total_price_net_amount": str(total_line.net.amount.quantize(Decimal("0.001"))), + "total_price_gross_amount": str( + total_line.gross.amount.quantize(Decimal("0.001")) + ), + "tax_rate": str(line.tax_rate.quantize(Decimal("0.01"))), + }