From 6543ea4533ff8bd3df696666d1179b2ab37a2753 Mon Sep 17 00:00:00 2001 From: Arjun Date: Mon, 13 Nov 2023 20:45:57 +0530 Subject: [PATCH] image upload done --- .gitignore | 4 + .../airtable_client.cpython-310.pyc | Bin 3257 -> 3257 bytes airlift/__pycache__/cli.cpython-310.pyc | Bin 2565 -> 2608 bytes airlift/__pycache__/cli_args.cpython-310.pyc | Bin 2523 -> 2703 bytes airlift/__pycache__/csv_data.cpython-310.pyc | Bin 2591 -> 4181 bytes .../dropbox_client.cpython-310.pyc | Bin 0 -> 1492 bytes .../google_drive_client.cpython-310.pyc | Bin 0 -> 429 bytes airlift/__pycache__/json_data.cpython-310.pyc | Bin 1356 -> 1356 bytes airlift/cli.py | 2 +- airlift/cli_args.py | 79 ++-- airlift/csv_data.py | 89 ++++- airlift/dropbox_client.py | 34 ++ airlift/json_data.py | 2 +- poetry.lock | 354 +++++++++++++++++- pyproject.toml | 2 + 15 files changed, 507 insertions(+), 59 deletions(-) create mode 100644 airlift/__pycache__/dropbox_client.cpython-310.pyc create mode 100644 airlift/__pycache__/google_drive_client.cpython-310.pyc create mode 100644 airlift/dropbox_client.py diff --git a/.gitignore b/.gitignore index 0b25010..7513014 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,7 @@ IMG_3046.jpg airlift_linux # Mac/OSX .DS_Store +client_secrets.json +settings.yml +marker_data_demo +upload_test_copy.sh diff --git a/airlift/__pycache__/airtable_client.cpython-310.pyc b/airlift/__pycache__/airtable_client.cpython-310.pyc index 7fd8ea5b1bf1357bf94d3f2003224faf498356e6..6d1ee017994c5e168dd2018ea082a4bdd006a970 100644 GIT binary patch delta 20 acmdlfxl@umpO=@50SNkc25jVB#{&R1G6hip delta 20 acmdlfxl@umpO=@50SH>oxo_lN#{&R1HU&}u diff --git a/airlift/__pycache__/cli.cpython-310.pyc b/airlift/__pycache__/cli.cpython-310.pyc index 5c4a4da50dd93bf874898c2e93de15a9321b2574..65cb5333cc54267794528650d43652dca317e91f 100644 GIT binary patch delta 390 zcmZn_*&xE3&&$ij00if)f>Iqf@^&*ZKAAj|DJRjfM4*N-iyMdqfmjHLg_~JwS@Q%^ z*lSqI7>ayLL}2pGOh9p#644ZnX2vGQ63zu&DVz%#85wF=i(`PITp-aJ<}9%qR-g{? z6z*Q2`VxuBam=PnFIgu~W!}jsIoY2@SyU0|j3RCjAqgU+K!o(V?f;+s5|c_*XzcQ3as&Mcg1l0z^oH2&u{aEYXvBS%VoBCMU9rGHOmPXEhNM zVB}x~VkRzT7A7Ezi4O>i3^pHRUBJkwI5~-38A!IVA7?a}?8hO&s4_X7BU!@(Xq+aK zo1Z3A5igMGrzu}#0L^yy5ClH}A`4h)MeKR2Q7Ds%1USe))e0-4#NJa!ixPS-) UkSt45etu4oB8cxX`4Oid0Jn)q0ssI2 diff --git a/airlift/__pycache__/cli_args.cpython-310.pyc b/airlift/__pycache__/cli_args.cpython-310.pyc index a887368e240150d91d882dce9f1693e95a912030..67f202285438febc0aaefebdc8b3d86b0bdf8b96 100644 GIT binary patch delta 441 zcmXX?O)mpM7&g=0YD+6oJs`_aUrX0VxQbNcBT_Bxa@4HOprJd>>{iqdAWn_UwZFhk zaCDV8_yd&)S2vDmYnDzj?>o=)yw8)Fc@CCC0qXbrTEx1VPLVtRbsz@7El&Za^v}Y{y1taqGqGfRYdw)xT~*l>BNkJ{(^#J_Yrpj3km_k(ZAC;rj7z@$^A_>Q31xfJ0P`4rJPOqq-+3P83Z zl&v)RBcmjv@@8(PPmC-=&cR`uIa%5mnKU^jZ(t3aJcmtbvJji?P^`8lPz zc?$UjC7Jno#Z^LOi8+}mi6D-`;c3g}_Af-i`AVO<$Ax9^p^5owfPHa#CXHFkQb)Z~0$SffsA;8MP#Ky?QB)}xX uD8$J0kL72P`s59qp^SQy*|x(5`>xf{s92pfJJ`* diff --git a/airlift/__pycache__/csv_data.cpython-310.pyc b/airlift/__pycache__/csv_data.cpython-310.pyc index 33ffa472c428a85c4f3a1c688bd31438dd0c3e0e..7150f2ed23c68a9e9c8d52eb8ab8a1496432adf4 100644 GIT binary patch literal 4181 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 PrarB(MP4aa3XAMN>`D>6 diff --git a/airlift/__pycache__/dropbox_client.cpython-310.pyc b/airlift/__pycache__/dropbox_client.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..df14631b0b614db00f1ac909a9d9194162937067 GIT binary patch literal 1492 zcmZWpPmdcl6t_KpGn-xL?g9mI2nd04XwphOa467Ki+ZW{z#>&0RkCKsPIgjfX7D&< zH<}=%t+*jR076QRd?jBwapcMc-kZr(TkvR}{hr@@e((LBUF`2i1ja|7eObZi#1b_7ch#?zV(=DwDXU5sM0@jqQdNrA` zjVBm#&mieD;)3qXp9NQUC|NVm*)ySVuABYmps{8@Fw|>TOS&XO_jGmpk(P;(Vvr1W zVGY`_R^d3ww8|!C_3^hCaxf{Bkb1C_4H5-*;%Xo-v&vMXVb2CTdmB7%^RtdPzqGz8 zrc=mTI)hvuhdy?hK_YBsV26cq^Ybb zZi<&Ow^aU4^ew2*-!I1V+>FJz)WuAurW&h6PbGiN7NyL2RV;KWyM*rSHpeGzf}MQ) zCNQJ&%7&b0d1g2d5sCgx)G z)^fQV?NS@1#eDU?P#wRhq)v<6K=(FV-d93>ad*{B_lA*mvFO&t4zaAL^gEES4bPKG z=E+>@0NH-q35!w{p!Gp@kpSG&t}~F8f~zclX`O{uHqf$ENh*gueb9JAbM$8E#75aX z0n9~Wl5X8>^*d-VBYS+qDW6M|wE8g)a~p9!FT_IOy3hG{i$t|M z`UpKP9msbMcFhCEe#^=WNJ6QtHnZ{Q~-$vr$ xW`I`~z_7ikG*6rBt3ShC?BK@hjnkW8n#zO^+Q`48pjIJD{iY-#lqG`u@-Ho6ng{>@ literal 0 HcmV?d00001 diff --git a/airlift/__pycache__/google_drive_client.cpython-310.pyc b/airlift/__pycache__/google_drive_client.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9184b4e33de4701158f6d2b0fb4acb55e6f98292 GIT binary patch literal 429 zcmYjN%SyyB6ixcFjxByiMJGQX;-KJeK-_gxN|ULTv_Ur{?Ja-3bGcb<4k#~Oz*3mW0#@cj) zgCN~>QVex3K8Z=7^|xmI;23Axs29;V%Vcd@QT;=u#ZXx_nntj?GqT&bt9_BJW_-xA z*7L1660REAiNP)Pb~+!mR5h=hnoFn16A5S3q~MBV%JtSyExk2ZoU%i%h8LR#i None: suffix = pathlib.Path(args.csv_file.name).suffix if "csv" in suffix: - data = csv_read(args.csv_file,args.fail_on_duplicate_csv_columns) + data = csv_read(args.csv_file,args.fail_on_duplicate_csv_columns,args.attachment_columns,args.dropbox_token) elif "json" in suffix: data = json_read(args.csv_file,args.fail_on_duplicate_csv_columns) else: diff --git a/airlift/cli_args.py b/airlift/cli_args.py index 2a01e5e..480b034 100644 --- a/airlift/cli_args.py +++ b/airlift/cli_args.py @@ -20,60 +20,67 @@ def parse_args(argv: Sequence[str]) -> argparse.Namespace: ) schema: ArgSchema = { - "POSITIONAL":{ - "csv_file":{ - "type":Path, - "help":"CSV or JSON file to upload", - "metavar":"FILE", + "POSITIONAL": { + "csv_file": { + "type": Path, + "help": "CSV or JSON file to upload", + "metavar": "FILE", } }, - "general_options":{ - "--token":{ - "help":"your Airtable personal access token", - "required":True, + "general_options": { + "--token": { + "help": "your Airtable personal access token", + "required": True, }, - "--base":{ - "help":"your Airtable Base ID", - "required":True, + "--base": { + "help": "your Airtable Base ID", + "required": True, }, - "--table":{ - "help":"your Airtable Table ID", - "required":True, + "--table": { + "help": "your Airtable Table ID", + "required": True, }, - "--log":{ - "type":Path, - "metavar":"FILE", - "help":"file to store program log", + "--log": { + "type": Path, + "metavar": "FILE", + "help": "file to store program log", }, - "--verbose":{ - "action":"store_true", - "help":"output debug information", + "--verbose": { + "action": "store_true", + "help": "output debug information", }, "--version": { "action": "version", "version": f"%(prog)s {__version__}", }, - "--workers":{ - "type":int, - "help":"total number of worker threads to upload your data (default: 1)" + "--workers": { + "type": int, + "help": "total number of worker threads to upload your data (default: 1)" }, ("-h", "--help"): { "action": "help", "help": "show this help message and exit", }, + "--dropbox-token":{ + "help":"enter your dropbox token here", + }, + }, - "column options":{ - "--disable-bypass-column-creation":{ - "action":"store_true", - "help": ( - "creates new columns that are not present in Airtable's table" - ), - }, + "column_options": { + "--disable-bypass-column-creation": { + "action": "store_true", + "help": "creates new columns that are not present in Airtable's table", + }, + "--attachment-columns": { + "nargs": "+", + "help": "specify one or more arguments", + "metavar": "ATTTACHMENT_COLUMNS", + }, }, - "validation options":{ - "--fail-on-duplicate-csv-columns":{ - "action":"store_true", - "help":( + "validation_options": { + "--fail-on-duplicate-csv-columns": { + "action": "store_true", + "help": ( "fail if CSV has duplicate columns" "\notherwise first column will be used" ), diff --git a/airlift/csv_data.py b/airlift/csv_data.py index 747a943..a130423 100644 --- a/airlift/csv_data.py +++ b/airlift/csv_data.py @@ -5,6 +5,12 @@ from typing import Any, Dict, Iterable, Iterator, List, Optional import datetime import email +import os +from airlift.dropbox_client import dropbox_client +from tqdm import tqdm +from queue import Queue, Empty +import multiprocessing +import concurrent.futures from airlift.utils_exceptions import CriticalError from airlift.airlift_data_guesser import guess_data_type @@ -14,15 +20,22 @@ logger = logging.getLogger(__name__) -def csv_read(file_path: Path,fail_on_dup:bool) -> List[CSVRowType]: +def csv_read(file_path: Path,fail_on_dup:bool,attachment_columns:List[str],dropbox_token:str) -> List[CSVRowType]: + dirname = os.path.dirname(file_path) try: with open(file_path,"r",encoding="utf-8-sig") as csv_file: - return _csv_read_rows(csv_file,fail_on_dup) + return _csv_read_rows(csv_file,fail_on_dup,dirname,attachment_columns,dropbox_token) except FileNotFoundError as e: logger.debug(f"error : {e}") raise CriticalError(f"File {file_path} not found") from e -def _csv_read_rows(csv_file:Iterable[str],fail_on_dup:bool) -> List[CSVRowType]: +def _csv_read_rows(csv_file:Iterable[str],fail_on_dup:bool,dirname:str,attachment_columns:List[str],dropbox_token:str) -> List[CSVRowType]: + + if dropbox_token: + dbx = dropbox_client(dropbox_token) + else: + dbx = None + reader = csv.DictReader(csv_file,restval="") if not reader.fieldnames: @@ -38,7 +51,7 @@ def _csv_read_rows(csv_file:Iterable[str],fail_on_dup:bool) -> List[CSVRowType]: else: rows = _remove_duplicates(rows) - converted_data = _convert_datatypes(rows) + converted_data = _convert_datatypes(rows,dirname,attachment_columns,dbx) records = [] @@ -47,24 +60,60 @@ def _csv_read_rows(csv_file:Iterable[str],fail_on_dup:bool) -> List[CSVRowType]: return records -def _convert_datatypes(rows:List[Dict]) -> List[CSVRowType]: - - for row in rows: - for key, value in row.items(): - - data_type = guess_data_type(value) - if data_type == "number": - row[key] = float(value) - elif data_type == "date": - row[key] = datetime.datetime.strptime(value, "%Y-%m-%d") - elif data_type == "email": - row[key] = email.utils.parseaddr(value)[1] - elif data_type == "bool": - row[key] = False if value.lower() == "false" else True +def _convert_datatypes(rows:List[Dict],dirname:str,attachment_columns:List[str],dbx:dropbox_client) -> List[CSVRowType]: + + manager = multiprocessing.Manager() + shared_list = manager.list() + + if dbx: + print("Uploading image to dropbox!") + + with tqdm(total = len(rows)) as progress_bar: + data_queue = Queue() + for row in rows: + data_queue.put(row) + + with concurrent.futures.ThreadPoolExecutor(max_workers=6) as executor: + futures = [executor.submit(_worker,dirname,attachment_columns,dbx,data_queue,shared_list,progress_bar) for _ in range(6)] + concurrent.futures.wait(futures,timeout=None) + + + return list(shared_list) + +def _worker(dirname:str,attachment_columns:List[str],dbx:dropbox_client,data_queue:Queue,shared_list,progress_bar): + while True: + try: + row = data_queue.get_nowait() + try: + for key, value in row.items(): + + data_type = guess_data_type(value) + if attachment_columns: + if dbx: + if key in attachment_columns: + if dirname: + row[key] = [{"url":dbx.upload_to_dropbox(f"{dirname}/{value}")}] + else: + row[key] = [{"url":dbx.upload_to_dropbox(f"{dirname}/{value}")}] + else: + raise CriticalError("dropbox token not provided! aborting the upload") + if data_type == "number": + row[key] = float(value) + elif data_type == "date": + row[key] = datetime.datetime.strptime(value, "%Y-%m-%d") + elif data_type == "email": + row[key] = email.utils.parseaddr(value)[1] + elif data_type == "bool": + row[key] = False if value.lower() == "false" else True + + shared_list.append(row) + progress_bar.update(1) + except Exception as e: + raise CriticalError(e) + except Empty: + break - return list(rows) - def _list_duplicates(lst: List[str]) -> List[str]: return [lst_item for lst_item, count in Counter(lst).items() if count > 1] diff --git a/airlift/dropbox_client.py b/airlift/dropbox_client.py new file mode 100644 index 0000000..3b328eb --- /dev/null +++ b/airlift/dropbox_client.py @@ -0,0 +1,34 @@ +from pydrive.drive import GoogleDrive +from pydrive.auth import GoogleAuth +import os +import dropbox +import logging +logger = logging.getLogger(__name__) +class dropbox_client: + def __init__(self,access_token): + + self.dbx = dropbox.Dropbox(access_token) + logger.info("Created a dropbox client") + + try: + self.dbx.files_create_folder("/airlift") + except dropbox.exceptions.ApiError as e: + print(f"The folder airlift already exists.") + + def upload_to_dropbox(self,filename): + with open(filename, 'rb') as f: + image_data = f.read() + image_name = os.path.basename(filename) + + dropbox_path = f"/airlift/{image_name}" + + # Upload the image + self.dbx.files_upload(image_data, dropbox_path) + + shared_link_metadata = self.dbx.sharing_create_shared_link(path=dropbox_path) + shared_url = shared_link_metadata.url + + + direct_download_url = shared_url.replace('www.dropbox.com', 'dl.dropboxusercontent.com').replace('?dl=0', '?dl=1') + + return direct_download_url \ No newline at end of file diff --git a/airlift/json_data.py b/airlift/json_data.py index 9a31ab0..743aa81 100644 --- a/airlift/json_data.py +++ b/airlift/json_data.py @@ -34,4 +34,4 @@ def _json_read_rows(json_file:Iterable[str],fail_on_dup:bool) -> List[CSVRowType records.append({"fields":each_data}) return records - \ No newline at end of file + \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index efdcbfc..ccd4139 100644 --- a/poetry.lock +++ b/poetry.lock @@ -14,6 +14,17 @@ files = [ [package.dependencies] typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} +[[package]] +name = "cachetools" +version = "5.3.2" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.3.2-py3-none-any.whl", hash = "sha256:861f35a13a451f94e301ce2bec7cac63e881232ccce7ed67fab9b5df4d3beaa1"}, + {file = "cachetools-5.3.2.tar.gz", hash = "sha256:086ee420196f7b2ab9ca2db2520aca326318b68fe5ba8bc4d49cca91add450f2"}, +] + [[package]] name = "certifi" version = "2023.7.22" @@ -135,6 +146,132 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "dropbox" +version = "11.36.2" +description = "Official Dropbox API Client" +optional = false +python-versions = "*" +files = [ + {file = "dropbox-11.36.2-py2-none-any.whl", hash = "sha256:afbfce2589b777ade1deaa2c186f3650c41e41cea0f1fac497a75112a171f8e2"}, + {file = "dropbox-11.36.2-py3-none-any.whl", hash = "sha256:a21e4d2bcbeb1d8067ff87969aea48792c9a8266182491153feff2be9c1b9c8f"}, + {file = "dropbox-11.36.2.tar.gz", hash = "sha256:d48d3d16d486c78b11c14a1c4a28a2611fbf5a0d0a358b861bfd9482e603c500"}, +] + +[package.dependencies] +requests = ">=2.16.2" +six = ">=1.12.0" +stone = ">=2" + +[[package]] +name = "google-api-core" +version = "2.14.0" +description = "Google API client core library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google-api-core-2.14.0.tar.gz", hash = "sha256:5368a4502b793d9bbf812a5912e13e4e69f9bd87f6efb508460c43f5bbd1ce41"}, + {file = "google_api_core-2.14.0-py3-none-any.whl", hash = "sha256:de2fb50ed34d47ddbb2bd2dcf680ee8fead46279f4ed6b16de362aca23a18952"}, +] + +[package.dependencies] +google-auth = ">=2.14.1,<3.0.dev0" +googleapis-common-protos = ">=1.56.2,<2.0.dev0" +protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0.dev0" +requests = ">=2.18.0,<3.0.0.dev0" + +[package.extras] +grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio (>=1.49.1,<2.0dev)", "grpcio-status (>=1.33.2,<2.0.dev0)", "grpcio-status (>=1.49.1,<2.0.dev0)"] +grpcgcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] +grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] + +[[package]] +name = "google-api-python-client" +version = "2.107.0" +description = "Google API Client Library for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google-api-python-client-2.107.0.tar.gz", hash = "sha256:ef6d4c1a17fe9ec0894fc6d4f61e751c4b859fb33f2ab5b881ceb0b80ba442ba"}, + {file = "google_api_python_client-2.107.0-py2.py3-none-any.whl", hash = "sha256:51d7bf676f41a77b00b7b9c72ace0c1db3dd5a4dd392a13ae897cf4f571a3539"}, +] + +[package.dependencies] +google-api-core = ">=1.31.5,<2.0.dev0 || >2.3.0,<3.0.0.dev0" +google-auth = ">=1.19.0,<3.0.0.dev0" +google-auth-httplib2 = ">=0.1.0" +httplib2 = ">=0.15.0,<1.dev0" +uritemplate = ">=3.0.1,<5" + +[[package]] +name = "google-auth" +version = "2.23.4" +description = "Google Authentication Library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google-auth-2.23.4.tar.gz", hash = "sha256:79905d6b1652187def79d491d6e23d0cbb3a21d3c7ba0dbaa9c8a01906b13ff3"}, + {file = "google_auth-2.23.4-py2.py3-none-any.whl", hash = "sha256:d4bbc92fe4b8bfd2f3e8d88e5ba7085935da208ee38a134fc280e7ce682a05f2"}, +] + +[package.dependencies] +cachetools = ">=2.0.0,<6.0" +pyasn1-modules = ">=0.2.1" +rsa = ">=3.1.4,<5" + +[package.extras] +aiohttp = ["aiohttp (>=3.6.2,<4.0.0.dev0)", "requests (>=2.20.0,<3.0.0.dev0)"] +enterprise-cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] +pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] +reauth = ["pyu2f (>=0.1.5)"] +requests = ["requests (>=2.20.0,<3.0.0.dev0)"] + +[[package]] +name = "google-auth-httplib2" +version = "0.1.1" +description = "Google Authentication Library: httplib2 transport" +optional = false +python-versions = "*" +files = [ + {file = "google-auth-httplib2-0.1.1.tar.gz", hash = "sha256:c64bc555fdc6dd788ea62ecf7bccffcf497bf77244887a3f3d7a5a02f8e3fc29"}, + {file = "google_auth_httplib2-0.1.1-py2.py3-none-any.whl", hash = "sha256:42c50900b8e4dcdf8222364d1f0efe32b8421fb6ed72f2613f12f75cc933478c"}, +] + +[package.dependencies] +google-auth = "*" +httplib2 = ">=0.19.0" + +[[package]] +name = "googleapis-common-protos" +version = "1.61.0" +description = "Common protobufs used in Google APIs" +optional = false +python-versions = ">=3.7" +files = [ + {file = "googleapis-common-protos-1.61.0.tar.gz", hash = "sha256:8a64866a97f6304a7179873a465d6eee97b7a24ec6cfd78e0f575e96b821240b"}, + {file = "googleapis_common_protos-1.61.0-py2.py3-none-any.whl", hash = "sha256:22f1915393bb3245343f6efe87f6fe868532efc12aa26b391b15132e1279f1c0"}, +] + +[package.dependencies] +protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0.dev0" + +[package.extras] +grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] + +[[package]] +name = "httplib2" +version = "0.22.0" +description = "A comprehensive HTTP client library." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "httplib2-0.22.0-py3-none-any.whl", hash = "sha256:14ae0a53c1ba8f3d37e9e27cf37eabb0fb9980f435ba405d546948b009dd64dc"}, + {file = "httplib2-0.22.0.tar.gz", hash = "sha256:d7a10bc5ef5ab08322488bde8c726eeee5c8618723fdb399597ec58f3d82df81"}, +] + +[package.dependencies] +pyparsing = {version = ">=2.4.2,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.0.2 || >3.0.2,<3.0.3 || >3.0.3,<4", markers = "python_version > \"3.0\""} + [[package]] name = "idna" version = "3.4" @@ -157,6 +294,55 @@ files = [ {file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"}, ] +[[package]] +name = "oauth2client" +version = "4.1.3" +description = "OAuth 2.0 client library" +optional = false +python-versions = "*" +files = [ + {file = "oauth2client-4.1.3-py2.py3-none-any.whl", hash = "sha256:b8a81cc5d60e2d364f0b1b98f958dbd472887acaf1a5b05e21c28c31a2d6d3ac"}, + {file = "oauth2client-4.1.3.tar.gz", hash = "sha256:d486741e451287f69568a4d26d70d9acd73a2bbfa275746c535b4209891cccc6"}, +] + +[package.dependencies] +httplib2 = ">=0.9.1" +pyasn1 = ">=0.1.7" +pyasn1-modules = ">=0.0.5" +rsa = ">=3.1.4" +six = ">=1.6.1" + +[[package]] +name = "ply" +version = "3.11" +description = "Python Lex & Yacc" +optional = false +python-versions = "*" +files = [ + {file = "ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce"}, + {file = "ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3"}, +] + +[[package]] +name = "protobuf" +version = "4.25.0" +description = "" +optional = false +python-versions = ">=3.8" +files = [ + {file = "protobuf-4.25.0-cp310-abi3-win32.whl", hash = "sha256:5c1203ac9f50e4853b0a0bfffd32c67118ef552a33942982eeab543f5c634395"}, + {file = "protobuf-4.25.0-cp310-abi3-win_amd64.whl", hash = "sha256:c40ff8f00aa737938c5378d461637d15c442a12275a81019cc2fef06d81c9419"}, + {file = "protobuf-4.25.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:cf21faba64cd2c9a3ed92b7a67f226296b10159dbb8fbc5e854fc90657d908e4"}, + {file = "protobuf-4.25.0-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:32ac2100b0e23412413d948c03060184d34a7c50b3e5d7524ee96ac2b10acf51"}, + {file = "protobuf-4.25.0-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:683dc44c61f2620b32ce4927de2108f3ebe8ccf2fd716e1e684e5a50da154054"}, + {file = "protobuf-4.25.0-cp38-cp38-win32.whl", hash = "sha256:1a3ba712877e6d37013cdc3476040ea1e313a6c2e1580836a94f76b3c176d575"}, + {file = "protobuf-4.25.0-cp38-cp38-win_amd64.whl", hash = "sha256:b2cf8b5d381f9378afe84618288b239e75665fe58d0f3fd5db400959274296e9"}, + {file = "protobuf-4.25.0-cp39-cp39-win32.whl", hash = "sha256:63714e79b761a37048c9701a37438aa29945cd2417a97076048232c1df07b701"}, + {file = "protobuf-4.25.0-cp39-cp39-win_amd64.whl", hash = "sha256:d94a33db8b7ddbd0af7c467475fb9fde0c705fb315a8433c0e2020942b863a1f"}, + {file = "protobuf-4.25.0-py3-none-any.whl", hash = "sha256:1a53d6f64b00eecf53b65ff4a8c23dc95df1fa1e97bb06b8122e5a64f49fc90a"}, + {file = "protobuf-4.25.0.tar.gz", hash = "sha256:68f7caf0d4f012fd194a301420cf6aa258366144d814f358c5b32558228afa7c"}, +] + [[package]] name = "pyairtable" version = "2.1.0.post1" @@ -175,6 +361,31 @@ requests = ">=2.22.0" typing-extensions = "*" urllib3 = ">=1.26" +[[package]] +name = "pyasn1" +version = "0.5.0" +description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "pyasn1-0.5.0-py2.py3-none-any.whl", hash = "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57"}, + {file = "pyasn1-0.5.0.tar.gz", hash = "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde"}, +] + +[[package]] +name = "pyasn1-modules" +version = "0.3.0" +description = "A collection of ASN.1-based protocols modules" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "pyasn1_modules-0.3.0-py2.py3-none-any.whl", hash = "sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d"}, + {file = "pyasn1_modules-0.3.0.tar.gz", hash = "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c"}, +] + +[package.dependencies] +pyasn1 = ">=0.4.6,<0.6.0" + [[package]] name = "pydantic" version = "2.4.2" @@ -312,6 +523,95 @@ files = [ [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" +[[package]] +name = "pydrive" +version = "1.3.1" +description = "Google Drive API made easy." +optional = false +python-versions = "*" +files = [ + {file = "PyDrive-1.3.1-py2-none-any.whl", hash = "sha256:5b94e971430722eb5c40a090f21df46b32e51399d747c1511796f63f902d1095"}, + {file = "PyDrive-1.3.1.tar.gz", hash = "sha256:83890dcc2278081c6e3f6a8da1f8083e25de0bcc8eb7c91374908c5549a20787"}, +] + +[package.dependencies] +google-api-python-client = ">=1.2" +oauth2client = ">=4.0.0" +PyYAML = ">=3.0" + +[[package]] +name = "pyparsing" +version = "3.1.1" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"}, + {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + [[package]] name = "requests" version = "2.31.0" @@ -333,6 +633,47 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "rsa" +version = "4.9" +description = "Pure-Python RSA implementation" +optional = false +python-versions = ">=3.6,<4" +files = [ + {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, + {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, +] + +[package.dependencies] +pyasn1 = ">=0.1.3" + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "stone" +version = "3.3.1" +description = "Stone is an interface description language (IDL) for APIs." +optional = false +python-versions = "*" +files = [ + {file = "stone-3.3.1-py2-none-any.whl", hash = "sha256:cd2f7f9056fc39b16c8fd46a26971dc5ccd30b5c2c246566cd2c0dd27ff96609"}, + {file = "stone-3.3.1-py3-none-any.whl", hash = "sha256:e15866fad249c11a963cce3bdbed37758f2e88c8ff4898616bc0caeb1e216047"}, + {file = "stone-3.3.1.tar.gz", hash = "sha256:4ef0397512f609757975f7ec09b35639d72ba7e3e17ce4ddf399578346b4cb50"}, +] + +[package.dependencies] +ply = ">=3.4" +six = ">=1.12.0" + [[package]] name = "tqdm" version = "4.66.1" @@ -364,6 +705,17 @@ files = [ {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, ] +[[package]] +name = "uritemplate" +version = "4.1.1" +description = "Implementation of RFC 6570 URI Templates" +optional = false +python-versions = ">=3.6" +files = [ + {file = "uritemplate-4.1.1-py2.py3-none-any.whl", hash = "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e"}, + {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, +] + [[package]] name = "urllib3" version = "2.0.7" @@ -384,4 +736,4 @@ zstd = ["zstandard (>=0.18.0)"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "802915c173faaa5ad970e1c64c42bd10b386e2afc5676d868a274ee65bb94b2e" +content-hash = "eaa8854cf19a131ea20fc01815b91920a07f46b7fa7c984e4d05bf0b3d19e15b" diff --git a/pyproject.toml b/pyproject.toml index 5436b54..37104cc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,8 @@ python = "^3.8" pyairtable = "^2.1.0.post1" requests = "^2.31.0" tqdm = "^4.66.1" +pydrive = "^1.3.1" +dropbox = "^11.36.2" [tool.poetry.group.dev.dependencies] pyairtable = "^2.1.0.post1"