diff --git a/experiments/ethereum-repo-clusters/.gitignore b/experiments/ethereum-repo-clusters/.gitignore index 58ae5f3c..552a22b5 100644 --- a/experiments/ethereum-repo-clusters/.gitignore +++ b/experiments/ethereum-repo-clusters/.gitignore @@ -35,4 +35,4 @@ ENV/ # Project specific data/ -output/ \ No newline at end of file +output*/ \ No newline at end of file diff --git a/experiments/ethereum-repo-clusters/CategorySummary.ipynb b/experiments/ethereum-repo-clusters/CategorySummary.ipynb index 9ca79d6b..8ccc2076 100644 --- a/experiments/ethereum-repo-clusters/CategorySummary.ipynb +++ b/experiments/ethereum-repo-clusters/CategorySummary.ipynb @@ -14,7 +14,7 @@ { "cell_type": "code", "execution_count": 2, - "id": "add99052-fecf-4130-9cc5-b7413c643864", + "id": "7ebc1141", "metadata": {}, "outputs": [ { @@ -39,16 +39,14 @@ " \n", " \n", " repo_artifact_id\n", - " project_id\n", - " project_name\n", - " display_name\n", " repo_artifact_namespace\n", " repo_artifact_name\n", " created_at\n", " updated_at\n", " star_count\n", " fork_count\n", - " ...\n", + " is_fork\n", + " num_packages_in_deps_dev\n", " is_actively_maintained\n", " final_recommendation\n", " processing_timestamp\n", @@ -65,16 +63,14 @@ " \n", " 0\n", " jXXy/fnXRva/c1jf/Weav9O3pWDHf/lVArjj0/oteUM=\n", - " KLkMfahLmIEtzAbihkJ4U9p0e/3zWn0iN6xBrwN++lU=\n", - " ethereum-attestation-service\n", - " Ethereum Attestation Service\n", " ethereum-attestation-service\n", " eas-docs-site\n", " 2022-11-09 19:39:56.000 UTC\n", " 2025-06-02 15:51:08.000 UTC\n", " 17\n", " 39\n", - " ...\n", + " False\n", + " 0\n", " True\n", " Developer Experience Tools\n", " 2025-06-06T00:55:35.737447\n", @@ -89,16 +85,14 @@ " \n", " 1\n", " Ymt6ZmVh75JL7ml3IM9hU32qFd+GB84kXijLttRFS+w=\n", - " 4JnmAZ2ikJpcjoRMX+2ZLxAQ10don2FQd6yPyDaBZ20=\n", - " erigontech\n", - " erigontech\n", " erigontech\n", " gmp-wasm\n", " 2020-12-16 08:27:02.000 UTC\n", " 2025-03-24 16:40:59.000 UTC\n", " 17\n", " 4\n", - " ...\n", + " False\n", + " 0\n", " True\n", " Cryptography & Primitives\n", " 2025-06-06T00:55:27.645719\n", @@ -113,16 +107,14 @@ " \n", " 2\n", " sTL/I78T3P6uyVN+En480uSHiTXT7UdHPmKQlvWxCkc=\n", - " 4JnmAZ2ikJpcjoRMX+2ZLxAQ10don2FQd6yPyDaBZ20=\n", - " erigontech\n", - " erigontech\n", " erigontech\n", " diagnostics\n", " 2023-02-22 11:05:42.000 UTC\n", " 2025-04-25 07:42:52.000 UTC\n", " 17\n", " 21\n", - " ...\n", + " False\n", + " 1\n", " True\n", " Infrastructure & Node Operations\n", " 2025-06-06T00:55:20.010674\n", @@ -137,16 +129,14 @@ " \n", " 3\n", " 9C23r6x0hqtbR/lB/1nYpc5KVgCtm4ga+lOJa4gd2cY=\n", - " Fs/BFdYMfeuzzzWPOX3dtOA6Z4AOJsB2eO2JIoZEzUo=\n", - " ensdomains\n", - " ENS\n", " ensdomains\n", " court\n", " 2018-05-02 19:41:02.000 UTC\n", " 2025-05-20 03:41:25.000 UTC\n", " 17\n", " 7\n", - " ...\n", + " False\n", + " 0\n", " True\n", " Application-Specific & Niche Tools\n", " 2025-06-06T00:55:11.604116\n", @@ -161,16 +151,14 @@ " \n", " 4\n", " j9aT6b4e9dCsCbJ42JXen90EHik4VhyLFvX2RjeiJGM=\n", - " Fs/BFdYMfeuzzzWPOX3dtOA6Z4AOJsB2eO2JIoZEzUo=\n", - " ensdomains\n", - " ENS\n", " ensdomains\n", " op-resolver\n", " 2022-11-03 11:14:36.000 UTC\n", " 2025-05-20 03:21:33.000 UTC\n", " 17\n", " 6\n", - " ...\n", + " False\n", + " 0\n", " True\n", " Interoperability & Cross-chain\n", " 2025-06-06T00:55:03.917944\n", @@ -203,22 +191,18 @@ " ...\n", " ...\n", " ...\n", - " ...\n", - " ...\n", " \n", " \n", " 5234\n", " AcuAtRmOCfY1rQN0rAx8iP5pdbgveBahZYSWK2leQq4=\n", - " AmxsQKHnsygqA+a7WJawinHjVclh84R+edks3EL9jiM=\n", - " fuellabs\n", - " Fuel Network\n", " fuellabs\n", " fuels-rs\n", " 2021-10-31 22:33:54.000 UTC\n", " 2025-06-03 17:34:29.000 UTC\n", " 43747\n", " 1355\n", - " ...\n", + " False\n", + " 13\n", " True\n", " Development Frameworks\n", " 2025-06-05T14:24:14.479181\n", @@ -233,16 +217,14 @@ " \n", " 5235\n", " JfvNeHojsqThZKXGfbrSSW4JIf2db88eIku67txzj9w=\n", - " vD6QgU2nKpWiutcCnblDJkVHtDkLDH6oyITV+xpe3+g=\n", - " go-ethereum\n", - " geth\n", " ethereum\n", " go-ethereum\n", " 2013-12-26 13:05:46.000 UTC\n", " 2025-06-03 16:54:54.000 UTC\n", " 49065\n", " 20888\n", - " ...\n", + " False\n", + " 2\n", " True\n", " Infrastructure & Node Operations\n", " 2025-06-05T14:24:08.096520\n", @@ -257,16 +239,14 @@ " \n", " 5236\n", " imBvQgAogfFYL0+hque3sUxe+dN53nsDQFoz1q1jgDA=\n", - " AmxsQKHnsygqA+a7WJawinHjVclh84R+edks3EL9jiM=\n", - " fuellabs\n", - " Fuel Network\n", " fuellabs\n", " fuel-core\n", " 2020-08-27 21:12:14.000 UTC\n", " 2025-06-03 17:34:30.000 UTC\n", " 57637\n", " 2852\n", - " ...\n", + " False\n", + " 45\n", " True\n", " Infrastructure & Node Operations\n", " 2025-06-05T14:24:01.176979\n", @@ -281,16 +261,14 @@ " \n", " 5237\n", " XK2KsRrMXU8N9WUAXb0V+X2pZWgx9H2UCtaJ6IONUC4=\n", - " AmxsQKHnsygqA+a7WJawinHjVclh84R+edks3EL9jiM=\n", - " fuellabs\n", - " Fuel Network\n", " fuellabs\n", " sway\n", " 2021-01-19 20:54:33.000 UTC\n", " 2025-06-03 17:34:31.000 UTC\n", " 62255\n", " 5405\n", - " ...\n", + " False\n", + " 29\n", " True\n", " Language & Compilation Tools\n", " 2025-06-05T14:23:54.181337\n", @@ -305,16 +283,14 @@ " \n", " 5238\n", " ACDSfw399At2CyBKEzgNCwOZ3zvC990eWZjGw+Z8isA=\n", - " cJt1yXO/geeLxyt++Pe5iU+kUyklaoGot3rHqrDNk1o=\n", - " base-org\n", - " Base\n", " base-org\n", " node\n", " 2023-02-01 13:55:02.000 UTC\n", " 2025-02-10 01:22:12.000 UTC\n", " 68568\n", " 2635\n", - " ...\n", + " False\n", + " 0\n", " True\n", " Infrastructure & Node Operations\n", " 2025-06-05T14:23:47.813647\n", @@ -328,7 +304,7 @@ " \n", " \n", "\n", - "

5239 rows × 22 columns

\n", + "

5239 rows × 19 columns

\n", "" ], "text/plain": [ @@ -345,32 +321,6 @@ "5237 XK2KsRrMXU8N9WUAXb0V+X2pZWgx9H2UCtaJ6IONUC4= \n", "5238 ACDSfw399At2CyBKEzgNCwOZ3zvC990eWZjGw+Z8isA= \n", "\n", - " project_id \\\n", - "0 KLkMfahLmIEtzAbihkJ4U9p0e/3zWn0iN6xBrwN++lU= \n", - "1 4JnmAZ2ikJpcjoRMX+2ZLxAQ10don2FQd6yPyDaBZ20= \n", - "2 4JnmAZ2ikJpcjoRMX+2ZLxAQ10don2FQd6yPyDaBZ20= \n", - "3 Fs/BFdYMfeuzzzWPOX3dtOA6Z4AOJsB2eO2JIoZEzUo= \n", - "4 Fs/BFdYMfeuzzzWPOX3dtOA6Z4AOJsB2eO2JIoZEzUo= \n", - "... ... \n", - "5234 AmxsQKHnsygqA+a7WJawinHjVclh84R+edks3EL9jiM= \n", - "5235 vD6QgU2nKpWiutcCnblDJkVHtDkLDH6oyITV+xpe3+g= \n", - "5236 AmxsQKHnsygqA+a7WJawinHjVclh84R+edks3EL9jiM= \n", - "5237 AmxsQKHnsygqA+a7WJawinHjVclh84R+edks3EL9jiM= \n", - "5238 cJt1yXO/geeLxyt++Pe5iU+kUyklaoGot3rHqrDNk1o= \n", - "\n", - " project_name display_name \\\n", - "0 ethereum-attestation-service Ethereum Attestation Service \n", - "1 erigontech erigontech \n", - "2 erigontech erigontech \n", - "3 ensdomains ENS \n", - "4 ensdomains ENS \n", - "... ... ... \n", - "5234 fuellabs Fuel Network \n", - "5235 go-ethereum geth \n", - "5236 fuellabs Fuel Network \n", - "5237 fuellabs Fuel Network \n", - "5238 base-org Base \n", - "\n", " repo_artifact_namespace repo_artifact_name \\\n", "0 ethereum-attestation-service eas-docs-site \n", "1 erigontech gmp-wasm \n", @@ -397,18 +347,18 @@ "5237 2021-01-19 20:54:33.000 UTC 2025-06-03 17:34:31.000 UTC 62255 \n", "5238 2023-02-01 13:55:02.000 UTC 2025-02-10 01:22:12.000 UTC 68568 \n", "\n", - " fork_count ... is_actively_maintained \\\n", - "0 39 ... True \n", - "1 4 ... True \n", - "2 21 ... True \n", - "3 7 ... True \n", - "4 6 ... True \n", - "... ... ... ... \n", - "5234 1355 ... True \n", - "5235 20888 ... True \n", - "5236 2852 ... True \n", - "5237 5405 ... True \n", - "5238 2635 ... True \n", + " fork_count is_fork num_packages_in_deps_dev is_actively_maintained \\\n", + "0 39 False 0 True \n", + "1 4 False 0 True \n", + "2 21 False 1 True \n", + "3 7 False 0 True \n", + "4 6 False 0 True \n", + "... ... ... ... ... \n", + "5234 1355 False 13 True \n", + "5235 20888 False 2 True \n", + "5236 2852 False 45 True \n", + "5237 5405 False 29 True \n", + "5238 2635 False 0 True \n", "\n", " final_recommendation processing_timestamp \\\n", "0 Developer Experience Tools 2025-06-06T00:55:35.737447 \n", @@ -475,7 +425,7 @@ "5237 Language & Compilation Tools \n", "5238 Infrastructure & Node Operations \n", "\n", - "[5239 rows x 22 columns]" + "[5239 rows x 19 columns]" ] }, "execution_count": 2, @@ -484,7 +434,7 @@ } ], "source": [ - "df = pd.read_parquet('output/ethereum_repos_unified.parquet')\n", + "df = pd.read_parquet('output_v1/ethereum_repos_unified.parquet')\n", "df[\"categorizations_list\"] = df[\"categorizations_json\"].apply(json.loads)\n", "\n", "def persona_to_category_map(cats_list):\n", @@ -493,18 +443,386 @@ "df_persona_cols = pd.json_normalize(df_persona_map)\n", "\n", "df = df.join(df_persona_cols)\n", - "df = df.drop(columns=[\"categorizations_list\", \"categorizations_json\", \"readme_md\"])\n", - "#df.to_csv('categorizations.csv')\n", + "df = df.drop(columns=[\"categorizations_list\", \"categorizations_json\", \"readme_md\",\n", + " \"project_id\", \"project_name\", \"display_name\"])\n", + "df.to_parquet('results/ethereum_repo_categories_v1.parquet')\n", "df" ] }, { "cell_type": "code", - "execution_count": null, - "id": "368d46ba-cedc-455d-a246-925b6c996090", + "execution_count": 3, + "id": "38245c13", "metadata": {}, - "outputs": [], - "source": [] + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
repo_artifact_idrepo_artifact_namespacerepo_artifact_namecreated_atupdated_atlanguagestar_countfork_countis_forknum_packages_in_deps_devis_actively_maintainedfinal_recommendationprocessing_timestampsummaryreadme_statustechnical_reviewer
0V52vAnlOFdRUfRIo8faESeAAwQDFIaOaQtBBCBw6a5Y=zypher-gameuzkge2023-12-29 01:28:42.000 UTC2025-02-13 23:01:42.000 UTCRust105False6TrueGaming & Metaverse Applications2025-06-29T17:38:19.154152uzkge is a universal zero-knowledge game engin...SUCCESSGaming & Metaverse Applications
1oEFKnNgSqEV+JQFLApgDkArvoXqpYJkPmIcoePwkKAc=zklinkprotocolzklink-docs-gitbook2023-06-15 09:30:45.000 UTC2025-04-01 04:49:42.000 UTC103False0TrueScaling & Layer‑2 Frameworks2025-06-29T17:38:16.295766zkLink X provides an aggregated rollup infrast...SUCCESSScaling & Layer‑2 Frameworks
29ShJYJxtK0uLqvR89mweTLTrIFwDmKmovC3LpAU73Es=zkblindzkblindnextjs2023-04-23 09:20:16.000 UTC2024-10-20 18:05:28.000 UTCCircom102False0TrueIdentity & Credentials2025-06-29T17:38:13.661183zkBind authenticates a user's employment at a ...SUCCESSIdentity & Credentials
3GVAT0dh82iHu/5NvZXbKkrn/f2FBx5PBFgof38zKYIU=zerolenddocs.zerolend.xyz2023-07-16 19:46:10.000 UTC2025-04-08 10:30:18.000 UTC106False0TrueDeFi Protocols & Financial Primitives2025-06-29T17:38:11.132290ZeroLend is a multi-chain, non-custodial lendi...SUCCESSDeFi Protocols & Financial Primitives
4983Z1VR9Jhb1ODQtDG1jr6tg8XDiTkb5eLroTzj2SBg=zeriontechwallet-core-ios2022-04-21 11:01:08.000 UTC2025-01-10 12:41:20.000 UTCSwift102False0TrueWallets & Account Abstraction2025-06-29T17:38:08.757093Zerion Wallet Core provides wallet functionali...SUCCESSWallets & Account Abstraction
...................................................
7044AcuAtRmOCfY1rQN0rAx8iP5pdbgveBahZYSWK2leQq4=fuellabsfuels-rs2021-10-31 22:33:54.000 UTC2025-06-25 10:19:58.000 UTCRust437111356False13TrueDevelopment Frameworks & Tooling2025-06-29T13:02:17.913939The fuels-rs project is a Rust SDK for the Fue...SUCCESSDevelopment Frameworks & Tooling
7045JfvNeHojsqThZKXGfbrSSW4JIf2db88eIku67txzj9w=ethereumgo-ethereum2013-12-26 13:05:46.000 UTC2025-06-25 14:38:46.000 UTCGo4919820940False2TrueExecution Clients & Core Protocol2025-06-29T13:02:16.065323Go Ethereum (geth) is a Golang implementation ...SUCCESSExecution Clients & Core Protocol
7046imBvQgAogfFYL0+hque3sUxe+dN53nsDQFoz1q1jgDA=fuellabsfuel-core2020-08-27 21:12:14.000 UTC2025-06-25 17:30:31.000 UTCRust576172850False45TrueNode Operations & DevOps2025-06-29T13:02:13.945394The Fuel client is a Rust implementation desig...SUCCESSNode Operations & DevOps
7047XK2KsRrMXU8N9WUAXb0V+X2pZWgx9H2UCtaJ6IONUC4=fuellabssway2021-01-19 20:54:33.000 UTC2025-06-25 15:39:40.000 UTCRust622245405False29TrueSmart‑Contract Languages & Compilers2025-06-29T13:02:11.752858Sway is a programming language designed for th...SUCCESSSmart‑Contract Languages & Compilers
7048ACDSfw399At2CyBKEzgNCwOZ3zvC990eWZjGw+Z8isA=base-orgnode2023-02-01 13:55:02.000 UTC2025-02-10 01:22:12.000 UTCShell685682635False0TrueNode Operations & DevOps2025-06-29T13:02:09.811785The Base Node project provides Docker configur...SUCCESSNode Operations & DevOps
\n", + "

7049 rows × 16 columns

\n", + "
" + ], + "text/plain": [ + " repo_artifact_id repo_artifact_namespace \\\n", + "0 V52vAnlOFdRUfRIo8faESeAAwQDFIaOaQtBBCBw6a5Y= zypher-game \n", + "1 oEFKnNgSqEV+JQFLApgDkArvoXqpYJkPmIcoePwkKAc= zklinkprotocol \n", + "2 9ShJYJxtK0uLqvR89mweTLTrIFwDmKmovC3LpAU73Es= zkblind \n", + "3 GVAT0dh82iHu/5NvZXbKkrn/f2FBx5PBFgof38zKYIU= zerolend \n", + "4 983Z1VR9Jhb1ODQtDG1jr6tg8XDiTkb5eLroTzj2SBg= zeriontech \n", + "... ... ... \n", + "7044 AcuAtRmOCfY1rQN0rAx8iP5pdbgveBahZYSWK2leQq4= fuellabs \n", + "7045 JfvNeHojsqThZKXGfbrSSW4JIf2db88eIku67txzj9w= ethereum \n", + "7046 imBvQgAogfFYL0+hque3sUxe+dN53nsDQFoz1q1jgDA= fuellabs \n", + "7047 XK2KsRrMXU8N9WUAXb0V+X2pZWgx9H2UCtaJ6IONUC4= fuellabs \n", + "7048 ACDSfw399At2CyBKEzgNCwOZ3zvC990eWZjGw+Z8isA= base-org \n", + "\n", + " repo_artifact_name created_at \\\n", + "0 uzkge 2023-12-29 01:28:42.000 UTC \n", + "1 zklink-docs-gitbook 2023-06-15 09:30:45.000 UTC \n", + "2 zkblindnextjs 2023-04-23 09:20:16.000 UTC \n", + "3 docs.zerolend.xyz 2023-07-16 19:46:10.000 UTC \n", + "4 wallet-core-ios 2022-04-21 11:01:08.000 UTC \n", + "... ... ... \n", + "7044 fuels-rs 2021-10-31 22:33:54.000 UTC \n", + "7045 go-ethereum 2013-12-26 13:05:46.000 UTC \n", + "7046 fuel-core 2020-08-27 21:12:14.000 UTC \n", + "7047 sway 2021-01-19 20:54:33.000 UTC \n", + "7048 node 2023-02-01 13:55:02.000 UTC \n", + "\n", + " updated_at language star_count fork_count is_fork \\\n", + "0 2025-02-13 23:01:42.000 UTC Rust 10 5 False \n", + "1 2025-04-01 04:49:42.000 UTC 10 3 False \n", + "2 2024-10-20 18:05:28.000 UTC Circom 10 2 False \n", + "3 2025-04-08 10:30:18.000 UTC 10 6 False \n", + "4 2025-01-10 12:41:20.000 UTC Swift 10 2 False \n", + "... ... ... ... ... ... \n", + "7044 2025-06-25 10:19:58.000 UTC Rust 43711 1356 False \n", + "7045 2025-06-25 14:38:46.000 UTC Go 49198 20940 False \n", + "7046 2025-06-25 17:30:31.000 UTC Rust 57617 2850 False \n", + "7047 2025-06-25 15:39:40.000 UTC Rust 62224 5405 False \n", + "7048 2025-02-10 01:22:12.000 UTC Shell 68568 2635 False \n", + "\n", + " num_packages_in_deps_dev is_actively_maintained \\\n", + "0 6 True \n", + "1 0 True \n", + "2 0 True \n", + "3 0 True \n", + "4 0 True \n", + "... ... ... \n", + "7044 13 True \n", + "7045 2 True \n", + "7046 45 True \n", + "7047 29 True \n", + "7048 0 True \n", + "\n", + " final_recommendation processing_timestamp \\\n", + "0 Gaming & Metaverse Applications 2025-06-29T17:38:19.154152 \n", + "1 Scaling & Layer‑2 Frameworks 2025-06-29T17:38:16.295766 \n", + "2 Identity & Credentials 2025-06-29T17:38:13.661183 \n", + "3 DeFi Protocols & Financial Primitives 2025-06-29T17:38:11.132290 \n", + "4 Wallets & Account Abstraction 2025-06-29T17:38:08.757093 \n", + "... ... ... \n", + "7044 Development Frameworks & Tooling 2025-06-29T13:02:17.913939 \n", + "7045 Execution Clients & Core Protocol 2025-06-29T13:02:16.065323 \n", + "7046 Node Operations & DevOps 2025-06-29T13:02:13.945394 \n", + "7047 Smart‑Contract Languages & Compilers 2025-06-29T13:02:11.752858 \n", + "7048 Node Operations & DevOps 2025-06-29T13:02:09.811785 \n", + "\n", + " summary readme_status \\\n", + "0 uzkge is a universal zero-knowledge game engin... SUCCESS \n", + "1 zkLink X provides an aggregated rollup infrast... SUCCESS \n", + "2 zkBind authenticates a user's employment at a ... SUCCESS \n", + "3 ZeroLend is a multi-chain, non-custodial lendi... SUCCESS \n", + "4 Zerion Wallet Core provides wallet functionali... SUCCESS \n", + "... ... ... \n", + "7044 The fuels-rs project is a Rust SDK for the Fue... SUCCESS \n", + "7045 Go Ethereum (geth) is a Golang implementation ... SUCCESS \n", + "7046 The Fuel client is a Rust implementation desig... SUCCESS \n", + "7047 Sway is a programming language designed for th... SUCCESS \n", + "7048 The Base Node project provides Docker configur... SUCCESS \n", + "\n", + " technical_reviewer \n", + "0 Gaming & Metaverse Applications \n", + "1 Scaling & Layer‑2 Frameworks \n", + "2 Identity & Credentials \n", + "3 DeFi Protocols & Financial Primitives \n", + "4 Wallets & Account Abstraction \n", + "... ... \n", + "7044 Development Frameworks & Tooling \n", + "7045 Execution Clients & Core Protocol \n", + "7046 Node Operations & DevOps \n", + "7047 Smart‑Contract Languages & Compilers \n", + "7048 Node Operations & DevOps \n", + "\n", + "[7049 rows x 16 columns]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.read_parquet('output_v2/ethereum_repos_unified.parquet')\n", + "df[\"categorizations_list\"] = df[\"categorizations_json\"].apply(json.loads)\n", + "\n", + "def persona_to_category_map(cats_list):\n", + " return { d[\"persona_name\"]: d[\"category\"] for d in cats_list }\n", + "df_persona_map = df[\"categorizations_list\"].apply(persona_to_category_map)\n", + "df_persona_cols = pd.json_normalize(df_persona_map)\n", + "\n", + "df = df.join(df_persona_cols)\n", + "df = df.drop(columns=[\"categorizations_list\", \"categorizations_json\", \"readme_md\"])\n", + "df.to_parquet('results/ethereum_repo_categories_v2.parquet')\n", + "df" + ] } ], "metadata": { @@ -523,7 +841,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.7" + "version": "3.11.5" } }, "nbformat": 4, diff --git a/experiments/ethereum-repo-clusters/README.md b/experiments/ethereum-repo-clusters/README.md index 5f5db141..c5e87dc4 100644 --- a/experiments/ethereum-repo-clusters/README.md +++ b/experiments/ethereum-repo-clusters/README.md @@ -1,71 +1,65 @@ # Ethereum Repo Clusters -A Python package for automatically clustering Ethereum development tools and libraries based on their README content using AI-driven analysis and multiple personas. +A Python module for categorizing Ethereum repositories using AI-based analysis. ## Overview This project implements a pipeline to: 1. Fetch repository data from the OSO (Open Source Observer) database. 2. Retrieve corresponding README files from GitHub. -3. Generate concise project summaries using Google's Gemini AI. -4. Employ multiple configurable AI personas to categorize each project based on its summary and metadata. -5. Consolidate these categorizations, using a star-count weighted approach for projects with multiple repositories, to produce a final recommended category. +3. Generate concise project summaries using Gemini AI. +4. Employ multiple configurable AI personas to categorize each project based on its full README content, summary, and metadata. +5. Consolidate categorizations and produce a final recommended category. The entire process is managed via a Command Line Interface (CLI). ## Features -- Fetches comprehensive repository data via OSO, including fork status and activity tracking. +- Quickly fetches comprehensive repository metadata via OSO. - Retrieves and processes README.md files from GitHub with robust error handling. -- Utilizes Google's Gemini AI for intelligent summary generation. -- Employs a multi-persona approach for nuanced project categorization. +- Utilizes Gemini AI for intelligent summary generation. - Supports an arbitrary number of configurable AI personas. -- Calculates final project recommendations using star-count weighted consolidation. -- Offers both modular pipeline and unified processing approaches. - Provides detailed tracking of repository status (active/inactive, fork/non-fork). - Handles empty or error READMEs gracefully with "UNCATEGORIZED" status. -- Includes timestamps for all categorization operations. - Test mode for quick runs on a subset of data. -- Outputs data at various stages in Parquet and CSV formats (with README text removed from CSV for readability). +- Outputs data at various stages in Parquet and CSV formats. - Supports easy resumption of processing and addition of new repositories. - Features comprehensive progress bars at multiple levels for better visibility into processing status. -- **Checkpoint System**: Automatically saves progress after each step, allowing for seamless recovery from interruptions. -- **Incremental Saving**: Saves results after processing each repository, ensuring no work is lost if the process is interrupted. -- **Resume Capability**: Automatically detects partially processed repositories and continues from where it left off. +- Automatically saves progress after each step, allowing for seamless recovery from interruptions and incremental processing. ## Prerequisites - Python 3.10+ -- Access to OSO, GitHub, and Google Gemini APIs. +- Poetry (for dependency management) +- Access to OSO, GitHub, and Gemini APIs. ## Installation 1. **Clone the repository:** ```bash - git clone + git clone https://github.com/ethereum/ethereum-repo-clusters.git cd ethereum-repo-clusters ``` -2. **Set up a virtual environment (recommended):** +2. **Install Poetry (if not already installed):** ```bash - python -m venv venv - source venv/bin/activate # On Windows use `venv\Scripts\activate` + curl -sSL https://install.python-poetry.org | python3 - ``` -3. **Install dependencies:** +3. **Install dependencies and activate the virtual environment:** ```bash - pip install -r requirements.txt + poetry install + poetry env activate ``` + This will: + - Create a virtual environment automatically + - Install all dependencies from `pyproject.toml` + - Activate the virtual environment -4. **Install the package in editable mode (optional, for development):** - ```bash - pip install -e . - ``` - -5. **Create a `.env` file** in the project root directory (`ethereum-repo-clusters/`) and add your API keys: +4. **Create a `.env` file** in the project root directory (`ethereum-repo-clusters/`) and add your API keys: ```env OSO_API_KEY="your_oso_api_key" - GITHUB_TOKEN="your_github_token" # A GitHub Personal Access Token with repo access + GITHUB_TOKEN="your_github_personal_access_token" GEMINI_API_KEY="your_gemini_api_key" ``` These keys are loaded via `ethereum-repo-clusters/config/settings.py`. @@ -91,7 +85,7 @@ The project uses a combination of a JSON configuration file and Python modules f - Edit this file to update the categorization taxonomy. - **Prompt Templates (`ethereum-repo-clusters/config/prompts/summary_prompts.py`):** - - Contains `SUMMARY_PROMPT` (for generating project summaries) and `TAGS_PROMPT` (for an auxiliary tag generation, currently not central to categorization). + - Contains `SUMMARY_PROMPT` (for generating project summaries). - These are used by the `AIService`. - **Core Settings (`ethereum-repo-clusters/config/settings.py`):** @@ -100,10 +94,15 @@ The project uses a combination of a JSON configuration file and Python modules f ## Usage (CLI) -The project is operated via the command line using `python -m ethereum-repo-clusters`. +The project is operated via the command line. **Poetry is recommended** for managing the virtual environment and dependencies. **General Command Structure:** ```bash +# With Poetry (recommended) +poetry run python -m ethereum-repo-clusters [GLOBAL_OPTIONS] COMMAND [COMMAND_OPTIONS] + +# Or activate Poetry shell first, then run directly +poetry shell python -m ethereum-repo-clusters [GLOBAL_OPTIONS] COMMAND [COMMAND_OPTIONS] ``` @@ -114,79 +113,57 @@ python -m ethereum-repo-clusters [GLOBAL_OPTIONS] COMMAND [COMMAND_OPTIONS] - **`fetch_repos`**: Fetches repository data from OSO and READMEs from GitHub. ```bash - python -m ethereum-repo-clusters fetch_repos + poetry run python -m ethereum-repo-clusters fetch_repos ``` - `--force-refresh`: Wipes existing raw repository data and re-fetches. - `--fetch-new-only`: Only fetches repositories that don't exist in current data. - **`generate_summaries`**: Generates AI summaries for fetched repositories. ```bash - python -m ethereum-repo-clusters generate_summaries + poetry run python -m ethereum-repo-clusters generate_summaries ``` - `--force-refresh`: Wipes existing summaries and regenerates them. - `--new-only`: Only generates summaries for repositories that don't have summaries yet. - **`categorize`**: Categorizes projects using all defined AI personas. ```bash - python -m ethereum-repo-clusters categorize + poetry run python -m ethereum-repo-clusters categorize ``` - `--force-refresh`: Wipes existing categorizations and re-runs. - `--persona `: Processes only the specified persona. Can be combined with `--force-refresh`. Example: ```bash - python -m ethereum-repo-clusters categorize --persona keyword_spotter --force-refresh + poetry run python -m ethereum-repo-clusters categorize --persona technical_reviewer --force-refresh ``` - `--new-only`: Only categorizes repositories that don't have categories yet. - **`consolidate`**: Consolidates categorizations from all personas and generates final project recommendations. ```bash - python -m ethereum-repo-clusters consolidate + poetry run python -m ethereum-repo-clusters consolidate ``` *(This step does not typically require a force-refresh as it always processes the latest categorized data.)* +- **`run_all`**: Runs the complete pipeline from start to finish. + ```bash + poetry run python -m ethereum-repo-clusters run_all + ``` + - `--force-refresh-all`: Wipes all existing data and re-runs the entire pipeline. + - `--use-unified`: Uses the unified processor approach (recommended). + **Persona Management (Informational):** The CLI includes commands related to personas, but due to refactoring, persona definitions are now managed directly in `ethereum-repo-clusters/config/prompts/personas.py`. These CLI commands are informational: -- `python -m ethereum-repo-clusters personas list`: Lists personas currently defined in `personas.py`. -- `python -m ethereum-repo-clusters personas add ...`: Provides instructions on how to add a persona by editing `personas.py`. -- `python -m ethereum-repo-clusters personas remove `: Provides instructions on how to remove a persona by editing `personas.py`. +- `poetry run python -m ethereum-repo-clusters personas list`: Lists personas currently defined in `personas.py`. +- `poetry run python -m ethereum-repo-clusters personas add ...`: Provides instructions on how to add a persona by editing `personas.py`. +- `poetry run python -m ethereum-repo-clusters personas remove `: Provides instructions on how to remove a persona by editing `personas.py`. **Example Full Run in Test Mode with Full Refresh:** ```bash -# Legacy pipeline approach -python -m ethereum-repo-clusters --test-mode run_all --force-refresh-all - -# New unified processor approach (recommended) -python -m ethereum-repo-clusters --test-mode run_all --force-refresh-all --use-unified +poetry run python -m ethereum-repo-clusters --test-mode run_all --force-refresh-all --use-unified ``` ## Workflow -### Legacy Pipeline (Step-by-Step) - -1. **Fetch Data (`fetch_repos`):** - - Repository metadata is fetched from OSO. - - README.md content is fetched from GitHub for these repositories. - - Output: `output/devtooling_raw.parquet` - -2. **Generate Summaries (`generate_summaries`):** - - READMEs are processed by Gemini AI to create concise summaries. - - Output: `output/devtooling_summarized.parquet` - -3. **Categorize by Persona (`categorize`):** - - Each project summary (with metadata) is evaluated by every defined AI persona. - - Each persona assigns a category based on its specific prompt and the global category list. - - Output: Individual Parquet files per persona in `output/categorized/` (e.g., `output/categorized/keyword_spotter.parquet`). - -4. **Consolidate Recommendations (`consolidate`):** - - Categorizations from all personas are merged. - - For each project: - - If it's a single-repository project, the recommendation is based on a star-weighted aggregation of persona assignments for that repo. - - If it's a multi-repository project, the recommendation is determined by a star-count weighted aggregation of all persona assignments across all its repositories. The category with the highest total star weight wins. - - Output: `output/devtooling_full.parquet` and `output/devtooling_consolidated.csv`. - -### New Unified Processor (Recommended) - -The new unified processor combines all steps into a single efficient pipeline: +The unified processor combines all steps into a single efficient pipeline: 1. **Process Repositories (`process_unified`):** - Repository metadata is fetched from OSO, including fork status and activity tracking. @@ -217,186 +194,17 @@ The unified processor offers several advantages: All output data is stored in the directory specified by `output_dir` in `pipeline_config.json` (default is `output/`). -### Legacy Pipeline Output - -- **`devtooling_raw.parquet`**: Raw data fetched from OSO, augmented with GitHub README content. -- **`devtooling_summarized.parquet`**: Repositories with their AI-generated summaries. -- **`categorized/.parquet`**: Dataframe for each persona, containing the original summary data plus that persona's assigned category and reason. -- **`devtooling_full.parquet`**: The final consolidated dataset, with one row per project, including the overall recommendation, total stars, repo count, sample summary, and individual persona category modes. -- **`devtooling_consolidated.csv`**: A CSV version of the final consolidated data for easier viewing. - ### Unified Processor Output -- **`ethereum_repos_unified.parquet`**: Comprehensive dataset containing all repositories with their metadata, summaries, and categorizations in a single structure. -- **`ethereum_repos_unified.csv`**: A CSV version of the unified data for easier viewing, with README text removed and long text fields truncated for readability. -- **`processing_checkpoint.json`**: Checkpoint file that tracks processing progress, allowing for seamless recovery from interruptions. - -### Unified Data Structure - -The unified processor creates a comprehensive data structure with the following key fields: - -```json -{ - "repo_artifact_id": "...", - "project_id": "...", - "repo_artifact_namespace": "...", - "repo_artifact_name": "...", - "is_fork": true/false, - "is_actively_maintained": true/false, - "last_updated": "2024-12-01", - "star_count": 100, - "readme_status": "SUCCESS/EMPTY/ERROR", - "summary": "...", - "categorizations": [ - { - "persona_name": "keyword_spotter", - "category": "Developer Tools", - "reason": "Contains keywords like 'CLI', 'build tool'...", - "timestamp": "2025-01-05T09:15:00Z" - }, - { - "persona_name": "senior_strategist", - "category": "Infrastructure", - "reason": "Mature project with strong adoption...", - "timestamp": "2025-01-05T09:15:01Z" - }, - { - "persona_name": "workflow_wizard", - "category": "Developer Tools", - "reason": "Streamlines development workflow...", - "timestamp": "2025-01-05T09:15:02Z" - } - ], - "final_recommendation": "Developer Tools", - "processing_timestamp": "2025-01-05T09:15:02Z" -} -``` +- **`ethereum_repos_unified.parquet`**: Complete dataset with all repository metadata, README content, summaries, persona categorizations, and final recommendations. +- **`ethereum_repos_unified.csv`**: CSV version of the unified dataset with README text removed for improved readability. -This structure makes it easy to: -- Track which repositories have been processed -- Identify repositories with errors or empty READMEs -- See the categorization from each persona with timestamps -- Filter repositories by fork status or activity -- Resume processing from where you left off - -## Development Notes -- The project uses `tqdm` for progress bars during long operations, with detailed progress tracking at multiple levels: - - Overall batch processing - - Repository processing within each batch - - README fetching for each repository - - Categorization with each persona -- `DataManager` class in `ethereum-repo-clusters/pipeline/data_manager.py` handles all data persistence (reading/writing Parquet files). -- `AIService` in `ethereum-repo-clusters/processing/ai_service.py` abstracts interactions with the Gemini API. -- `UnifiedProcessor` in `ethereum-repo-clusters/pipeline/unified_processor.py` provides the new streamlined processing approach. -- The CLI in `ethereum-repo-clusters/cli/main_cli.py` supports both legacy and unified processing approaches. -- Output files are saved to the local `output/` directory in the current repository. - -## New CLI Commands - -### Unified Processing +### Step-by-Step Pipeline Output (Alternative) -```bash -# Process repositories with the unified processor -python -m ethereum-repo-clusters process_unified [OPTIONS] - -# Options: -# --force-refresh Force refresh all data, ignoring existing. -# --include-forks Include forked repositories in processing. -# --include-inactive Include repositories not updated in the last year. -# --limit INTEGER Limit the number of repositories to process. -``` - -### Run All with Unified Processor - -```bash -# Run the entire pipeline using the unified processor -python -m ethereum-repo-clusters run_all --use-unified [OPTIONS] +If using the step-by-step approach instead of the unified processor: -# Additional options with --use-unified: -# --include-forks Include forked repositories in processing. -# --include-inactive Include repositories not updated in the last year. -``` - -## Adding New Repositories - -To add new repositories to the analysis: - -1. The unified processor automatically detects which repositories have already been processed. -2. New repositories from OSO will be processed automatically on the next run. -3. To add repositories manually, you can: - - Update the OSO query in `fetcher.py` to include additional repositories. - - Create a custom script that adds repositories to the unified data structure. - -## Error Handling - -The unified processor handles errors gracefully: - -- Empty READMEs: Marked with `readme_status="EMPTY"` and categorized as "UNCATEGORIZED". -- Error fetching README: Marked with `readme_status="ERROR"` and categorized as "UNCATEGORIZED". -- API errors during categorization: The specific persona's categorization is marked as "UNCATEGORIZED" with the error reason. - -This approach ensures that all repositories are included in the final output, even if they couldn't be fully processed. - -## Checkpoint System - -The unified processor now includes a robust checkpoint system that makes it resilient to interruptions: - -### How It Works - -1. **Incremental Saving**: Results are saved after processing each repository, not just at the end. -2. **Checkpoint File**: A JSON file (`output/processing_checkpoint.json`) tracks: - - Which repositories have been fully processed - - Which repositories are partially processed and their current state - - The last repository that was successfully processed - -3. **Granular Progress Tracking**: The checkpoint tracks progress at multiple levels: - - README fetching status - - Summary generation status - - Which personas have completed categorization - -4. **Resume Logic**: When restarted after an interruption, the processor: - - Skips repositories that have been fully processed - - Continues from where it left off for partially processed repositories - - Preserves all work that was completed before the interruption - -5. **Space Optimization**: Once a repository is fully processed, its partial results are removed from the checkpoint file to save space. - -### Benefits - -- **No Lost Work**: Even if interrupted during a long-running process, no work is lost. -- **API Efficiency**: Avoids redundant API calls to GitHub and Gemini, saving rate limits and costs. -- **Time Savings**: Picks up exactly where it left off, avoiding redundant processing. -- **Resilience**: Handles network issues, API timeouts, and other temporary failures gracefully. - -### Example Checkpoint Structure - -```json -{ - "last_processed_repo_id": "ethereum/solidity", - "processed_repos": ["openzeppelin/openzeppelin-contracts", "ethereum/solidity"], - "partial_results": { - "ipfs/kubo": { - "readme_fetched": true, - "readme_status": "SUCCESS", - "summary_generated": true, - "personas_completed": ["protocol_architect", "ecosystem_analyst"], - "categorizations": [ - { - "persona_name": "protocol_architect", - "category": "Infrastructure & Node Operations", - "reason": "...", - "timestamp": "2025-06-05T13:53:30.903574" - }, - { - "persona_name": "ecosystem_analyst", - "category": "Infrastructure & Node Operations", - "reason": "...", - "timestamp": "2025-06-05T13:53:32.238039" - } - ] - } - } -} -``` - -This checkpoint system ensures that the processing pipeline is robust and can handle interruptions gracefully, making it suitable for processing large numbers of repositories over extended periods. +- **`devtooling_raw.parquet`**: Raw data fetched from OSO, augmented with GitHub README content. +- **`devtooling_summarized.parquet`**: Repositories with their AI-generated summaries. +- **`categorized/.parquet`**: Dataframe for each persona, containing the original summary data plus that persona's assigned category and reason. +- **`devtooling_full.parquet`**: The final consolidated dataset, with one row per project, including the overall recommendation, total stars, repo count, sample summary, and individual persona category modes. +- **`devtooling_consolidated.csv`**: CSV version of the final consolidated dataset. \ No newline at end of file diff --git a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/config_manager.py b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/config_manager.py index a9fb5bb1..17ee987d 100644 --- a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/config_manager.py +++ b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/config_manager.py @@ -2,7 +2,7 @@ from pathlib import Path from typing import List, Dict, Any from .settings import PROJECT_ROOT, GEMINI_API_KEY, OSO_API_KEY, GITHUB_TOKEN, GEMINI_MODEL, OUTPUT_DIR -from .prompts.summary_prompts import SUMMARY_PROMPT, TAGS_PROMPT +from .prompts.summary_prompts import SUMMARY_PROMPT @@ -44,7 +44,6 @@ def _get_default_config(self) -> Dict[str, Any]: "output_dir": str(OUTPUT_DIR), "gemini_model": GEMINI_MODEL, "summary_prompt_template": SUMMARY_PROMPT, - "tags_prompt_template": TAGS_PROMPT, "test_mode": False, "test_mode_limit": 5, "batch_size_summaries": 50, @@ -108,6 +107,9 @@ def get_batch_size_summaries(self) -> int: def get_batch_size_categorization(self) -> int: return self.get("batch_size_categorization", 10) + def get_min_stars(self) -> int: + return self.get("min_stars", 0) + def get_categories(self) -> List[Dict[str, str]]: """Gets the categories directly from the categories.py module.""" from .prompts.categories import CATEGORIES @@ -121,9 +123,6 @@ def get_category_names(self) -> List[str]: def get_summary_prompt_template(self) -> str: return self.get("summary_prompt_template", "") - def get_tags_prompt_template(self) -> str: - return self.get("tags_prompt_template", "") - if __name__ == "__main__": # Example usage: config_manager = ConfigManager() diff --git a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/__init__.py b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/__init__.py index c22d1787..b3ae9942 100644 --- a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/__init__.py +++ b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/__init__.py @@ -1,11 +1,10 @@ from .categories import CATEGORIES, CATEGORY_NAMES from .personas import PERSONAS -from .summary_prompts import SUMMARY_PROMPT, TAGS_PROMPT +from .summary_prompts import SUMMARY_PROMPT __all__ = [ 'CATEGORIES', 'CATEGORY_NAMES', 'PERSONAS', 'SUMMARY_PROMPT', - 'TAGS_PROMPT', ] diff --git a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/categories.py b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/categories.py index bd201d31..df7e9767 100644 --- a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/categories.py +++ b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/categories.py @@ -1,207 +1,83 @@ CATEGORIES = [ - # DeFi Application Categories { - "category": "Lending & Borrowing Protocols", - "description": ( - "Lending & Borrowing Protocols include implementations and SDKs for collateralized lending markets, " - "flash loans, interest rate models, and liquidation mechanisms. These tools handle asset management, " - "risk scoring, and pool accounting, enabling users to lend or borrow assets in a trust-minimized way." - ) + "category": "Execution Clients & Core Protocol", + "description": "Implementations of the Ethereum execution layer (e.g., Geth, Nethermind) plus low‑level consensus or EVM research repos. Anything that validates blocks or directly extends the core protocol logic belongs here." }, { - "category": "Decentralized Exchanges (DEXs)", - "description": ( - "DEXs power peer-to-peer asset swaps and liquidity provision. This includes AMM (automated market maker) " - "frameworks, order book DEXes, routers, aggregators, and liquidity management libraries. They also often " - "support advanced trading mechanisms like TWAPs, limit orders, and MEV protection." - ) + "category": "Scaling & Layer‑2 Frameworks", + "description": "Rollup SDKs, optimistic & zk proof systems, shared sequencers, data‑availability layers, and tooling that lets teams spin up or operate an L2 or sidechain." }, { - "category": "Derivatives & Synthetic Assets", - "description": ( - "Derivatives & Synthetic Assets frameworks implement perpetual futures, options, and collateralized synthetic " - "asset systems. These toolkits involve complex pricing oracles, risk engines, margin systems, and settlement layers." - ) + "category": "Interoperability & Bridges", + "description": "Cross‑chain bridges, messaging buses, generalized state‑proof frameworks, and liquidity routers focused on moving assets or data between networks." }, { - "category": "Stablecoin Infrastructure", - "description": ( - "Stablecoin Infrastructure includes minting contracts, collateralization engines, algorithmic stabilization mechanisms, " - "and off-chain attestation integrations. It also encompasses tools for analyzing backing ratios and peg health." - ) + "category": "Cryptography & Zero‑Knowledge Primitives", + "description": "Reusable cryptographic libraries—hash functions, elliptic‑curve math, SNARK/STARK circuits, proof systems, and related tooling not tied to a single application." }, { - "category": "Oracles & Price Feeds", - "description": ( - "Oracles & Price Feeds provide real-world and cross-chain data into smart contracts. This category covers push-based oracles, " - "pull-based on-demand queries, cryptoeconomic staking oracles, and off-chain data relayers." - ) + "category": "Oracle Networks & Data Feeds", + "description": "Push or pull‑based oracle contracts, off‑chain reporters, commit‑reveal schemes, and services that bring real‑world or cross‑chain data onchain." }, { - "category": "Vaults, Yield Strategies & Aggregators", - "description": ( - "These tools optimize capital across yield-bearing protocols. They include yield routers, auto-compounding vaults, and rebalancers, " - "as well as SDKs to model risk-return profiles and dynamically allocate capital across farms and lending markets." - ) + "category": "Smart‑Contract Languages & Compilers", + "description": "Compilers, interpreters, transpilers, language servers, and DSLs that translate high‑level code (Solidity, Vyper, Huff, etc.) into EVM bytecode." }, { - "category": "Asset Management & Portfolio Tooling", - "description": ( - "Asset Management tooling includes interfaces and libraries for building rebalancing strategies, vault-based funds, on-chain ETFs, " - "and automated index trackers. They often incorporate fee structures, role-based access, and compliance checks." - ) + "category": "Development Frameworks & Tooling", + "description": "Opinionated toolchains (Hardhat, Foundry, Brownie, DappTools) that scaffold, test, and deploy contracts, including plugin ecosystems and CLIs." }, { - "category": "DeFi Security & Monitoring", - "description": ( - "Security tools for DeFi include real-time exploit detectors, anomaly detection systems, pause mechanisms, multisig enforcers, " - "and post-mortem forensic tools. Monitoring dashboards and alerting frameworks fall here as well." - ) + "category": "Testing & Formal Verification", + "description": "Unit‑test harnesses, fuzzers, static analyzers, symbolic execution engines, and formal verification suites that surface correctness or security issues pre‑deployment." }, { - "category": "Governance & DAO Tooling", - "description": ( - "Governance & DAO Tooling enables on-chain proposal management, token-weighted voting, off-chain signaling, execution queues, " - "and guardrails for DeFi governance systems. Includes snapshot integration, timelocks, and delegate management interfaces." - ) + "category": "Deployment & Upgrade Management", + "description": "Libraries and services that automate contract deployment, versioning, proxy patterns, CREATE2 determinism, and governance‑controlled upgrades." }, { - "category": "Liquidity Bootstrapping & Token Distribution", - "description": ( - "This includes tools for liquidity mining, airdrops, vesting contracts, bonding curves, and initial token offerings. " - "They facilitate community-led distribution, price discovery, and progressive decentralization of DeFi protocols." - ) + "category": "Node Operations & DevOps", + "description": "Scripts, dashboards, container images, and orchestration tools for running or monitoring full nodes, validators, archival nodes, or RPC endpoints." }, { - "category": "DeFi Analytics & Dashboards", - "description": ( - "These are SDKs, APIs, and frontends for aggregating on-chain DeFi metrics—TVL, yield, volume, and user activity. " - "Includes data pipelines, Dune-compatible libraries, subgraphs, and event-based ETL infrastructure tailored to DeFi." - ) + "category": "Data Indexing & Analytics", + "description": "Subgraph definitions, ETL pipelines, time‑series databases, and API servers that structure onchain data for querying, dashboards, or research." }, { - "category": "Cross-chain DeFi Infrastructure", - "description": ( - "These tools support multi-chain liquidity routing, cross-chain yield farming, state relays, and synthetic asset issuance. " - "They abstract away bridging mechanics, offering seamless user and liquidity migration across ecosystems." - ) + "category": "Wallets & Account Abstraction", + "description": "Key‑management libraries, signature middlewares (EIP‑4337), wallet SDKs, browser extensions, mobile wallets, and transaction‑building helpers." }, { - "category": "User Interface & Integration SDKs", - "description": ( - "SDKs and frontend libraries for integrating DeFi functionality into wallets, dApps, and aggregators. Includes trade UIs, " - "Zap interfaces, gas estimators, and batch transaction helpers to improve DeFi UX." - ) + "category": "Identity & Credentials", + "description": "ENS, decentralized identity, verifiable‑credential frameworks, reputation scores, soul‑bound token standards, and onchain attestations." }, { - "category": "Simulation & Risk Modeling", - "description": ( - "Tools that simulate user positions, economic incentives, or protocol upgrades. They model protocol resilience, agent behavior, " - "market shocks, and contagion scenarios, often using agent-based or Monte Carlo methods for risk-aware design." - ) + "category": "DAO & Governance Systems", + "description": "Token‐weighted voting modules, off‑chain signaling, delegate dashboards, execution timelocks, proposal simulators, and treasury management tooling." }, - - # Developer Tool Categories - { - "category": "Language & Compilation Tools", - "description": ( - "Language & Compilation Tools include compilers, interpreters, language servers, " - "and syntax utilities for smart-contract development. They translate high-level " - "source code into EVM bytecode, perform static analysis, and enable features like " - "symbolic execution, forming the foundation for all higher-level tooling." - ) - }, - { - "category": "Core Protocol Interfaces", - "description": ( - "Core Protocol Interfaces are libraries and SDKs that provide reusable building blocks " - "for blockchain developers—smart contract libraries, JSON-RPC clients, transaction builders, " - "wallet and key management, authorization, signature handling, and ABI encoding/decoding. " - "They can power the core operations of many dApps and services." - ) - }, - { - "category": "Development Frameworks", - "description": ( - "Development Frameworks are opinionated, end-to-end toolchains that scaffold, build, " - "test, and deploy smart-contract projects. They bundle CLIs, IDE integrations, task " - "runners, local networks, hot-reloading, and plugin ecosystems to enforce conventions " - "and automate workflows from project setup through to frontend integration." - ) - }, - { - "category": "Deployment & Lifecycle Management", - "description": ( - "Deployment & Lifecycle Management tools handle contract deployment, upgrades, and " - "on-chain migrations. They automate predictable CREATE2 strategies, proxy pattern " - "management, cross-network publishes, and governance hooks, while integrating safety " - "checks and test-suite validations to maintain contract integrity." - ) - }, - { - "category": "Testing & Verification Tools", - "description": ( - "Testing & Verification Tools provide frameworks for unit testing, property-based fuzzing, " - "symbolic execution, formal verification, and coverage analysis. They integrate vulnerability " - "scanners, static analyzers, and coverage reporters to identify edge-case failures and ensure " - "on-chain correctness." - ) - }, - { - "category": "Developer Experience Tools", - "description": ( - "Developer Experience Tools are lightweight plugins and utilities that boost productivity " - "and enforce code consistency. This category includes editor extensions, linters, formatters, " - "code generators, documentation generators, and small CLI helpers." - ) - }, - { - "category": "Infrastructure & Node Operations", - "description": ( - "Infrastructure & Node Operations encompass tools for running, coordinating, and scaling " - "blockchain nodes and peer-to-peer networks. They cover RPC providers, telemetry collectors, " - "log aggregators, gossip-based messaging layers, peer discovery and connection management, " - "and automation scripts to ensure reliable network participation." - ) + { + "category": "DeFi Protocols & Financial Primitives", + "description": "Lending markets, DEXes, derivatives, yield optimizers, stablecoins, liquidity bootstrapping, onchain indices, and associated SDKs." }, { - "category": "Data Indexing & Analytics", - "description": ( - "Data Indexing & Analytics tools ingest, process, and visualize on-chain data. They provide " - "GraphQL and REST APIs over processed datasets, real-time event streaming, and libraries or " - "dashboards for analyzing blockchain metrics." - ) - }, - { - "category": "Interoperability & Cross-chain", - "description": ( - "Interoperability & Cross-chain covers bridging frameworks, cross-chain messaging protocols, " - "and Superchain interoperability tooling. These libraries enable seamless asset transfers, " - "state proofs, and communication across multiple networks." - ) - }, - { - "category": "Cryptography & Primitives", - "description": ( - "Cryptography & Primitives includes low-level cryptographic libraries and building blocks—" - "hash functions, signature schemes, Merkle trees, zero-knowledge proof primitives, and " - "encryption utilities—optimized for security and performance." - ) - }, - { - "category": "Application-Specific & Niche Tools", - "description": ( - "Application-Specific & Niche Tools are libraries and SDKs tailored to very narrow use cases " - "(e.g., DeFi adapters, NFT marketplaces, governance dashboards). They serve specific projects " - "but do not have broad applicability or reusability across the ecosystem." - ) - }, - { - "category": "Others", - "description": ( - "Others is a catch-all for repositories with limited usage or insufficient information—" - "empty projects, single-file utilities, or items that cannot be reasonably categorized." - ) + "category": "NFTs & Digital Asset Protocols", + "description": "ERC‑721/1155 implementations, metadata standards, onchain creators' platforms, marketplace contracts, royalty engines, and fractionalization tooling." + }, + { + "category": "Gaming & Metaverse Applications", + "description": "Onchain game engines, asset composability layers, play‑to‑earn economies, and metaverse SDKs focused primarily on interactive entertainment." + }, + { + "category": "Social & Consumer Applications", + "description": "Protocols or SDKs for social graphs, content platforms, messaging, ticketing, subscriptions, and other consumer‑oriented experiences." + }, + { + "category": "Storage & Data Availability", + "description": "IPFS pinning tools, Filecoin/Arweave clients, EigenDA or Celestia adapters, and libraries that persist or serve large blobs and proofs." + }, + { + "category": "Security Monitoring & Incident Response", + "description": "Real‑time threat detectors, alerting networks (e.g., Forta), exploit simulators, pause/kill switches, forensic analysis, and post‑mortem tooling." } ] diff --git a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/personas.py b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/personas.py index 209515cf..359e7cce 100644 --- a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/personas.py +++ b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/personas.py @@ -1,110 +1,74 @@ PERSONAS = [ { - "name": "protocol_architect", - "title": "Protocol & Infrastructure Architect", + "name": "technical_reviewer", + "title": "Technical Reviewer", "description": ( - "You evaluate projects based on their technical architecture, infrastructure role, " - "and protocol design patterns. You focus on how well the project implements DeFi primitives, " - "contributes to ecosystem stability, and maintains technical dependencies." + "Your goal is to spot the primary on‑chain or off‑chain function the repo enables, " + "independent of business hype or UI polish." ), "prompt": ( - "As a Protocol & Infrastructure Architect, analyze the project's technical foundations, " - "infrastructure role, and protocol design.\n\n" - "Summary: {summary}\n" + "You are a Technical Reviewer. Analyze this single repository and categorize it.\n\n" + "Repository Summary: {summary}\n" + "Primary Language: {language}\n" "Stars: {star_count} | Forks: {fork_count}\n" "Created: {created_at} | Updated: {updated_at}\n\n" - "Based on the technical architecture, infrastructure contribution, and protocol design, " - "choose one of the categories below:\n" + "Full README Content:\n{readme_md}\n" + "Available categories:\n" "{categories}\n\n" - "Respond in JSON:\n" + "CRITICAL: Respond with ONLY a single JSON object in this exact format:\n" "{{\n" ' "assigned_tag": "category name",\n' - ' "reason": "analysis of protocol architecture, infrastructure role, technical dependencies, and ecosystem stability"\n' - "}}" - ), - }, - { - "name": "ecosystem_analyst", - "title": "Ecosystem Growth Analyst", - "description": ( - "You assess projects based on their potential to grow the Ethereum DeFi ecosystem, " - "their user adoption metrics, and their contribution to composability and innovation." - ), - "prompt": ( - "As an Ecosystem Growth Analyst, evaluate the project's impact on DeFi ecosystem growth.\n\n" - "Summary: {summary}\n" - "Stars: {star_count} | Forks: {fork_count}\n" - "Created: {created_at} | Updated: {updated_at}\n\n" - "Select the category that best represents its ecosystem role:\n" - "{categories}\n\n" - "Respond in JSON:\n" - "{{\n" - ' "assigned_tag": "category name",\n' - ' "reason": "analysis of ecosystem impact, adoption potential, and composability"\n' - "}}" - ), - }, - { - "name": "security_researcher", - "title": "Security & Risk Researcher", - "description": ( - "You focus on security practices, risk management approaches, and the project's " - "contribution to making DeFi safer and more resilient." - ), - "prompt": ( - "As a Security & Risk Researcher, assess the project's security posture and risk management.\n\n" - "Summary: {summary}\n" - "Stars: {star_count} | Forks: {fork_count}\n" - "Created: {created_at} | Updated: {updated_at}\n\n" - "Choose the category that best reflects its security and risk management approach:\n" - "{categories}\n\n" - "Respond in JSON:\n" - "{{\n" - ' "assigned_tag": "category name",\n' - ' "reason": "analysis of security practices, risk management, and safety features"\n' - "}}" - ), - }, - { - "name": "user_experience_advocate", - "title": "User Experience Advocate", - "description": ( - "You evaluate projects based on their user experience, accessibility, and potential " - "to onboard new users to DeFi. You focus on usability and integration capabilities." - ), - "prompt": ( - "As a User Experience Advocate, assess the project's usability and accessibility.\n\n" - "Summary: {summary}\n" - "Stars: {star_count} | Forks: {fork_count}\n" - "Created: {created_at} | Updated: {updated_at}\n\n" - "Select the category that best represents its user experience focus:\n" - "{categories}\n\n" - "Respond in JSON:\n" - "{{\n" - ' "assigned_tag": "category name",\n' - ' "reason": "analysis of user experience, accessibility, and onboarding potential"\n' - "}}" - ), + ' "reason": "brief technical justification"\n' + "}}\n\n" + "Do not include any other text, explanations, or formatting. Do not mention batch processing or multiple projects." + ) }, - { - "name": "governance_specialist", - "title": "Governance & Decentralization Specialist", - "description": ( - "You analyze projects based on their governance mechanisms, decentralization approach, " - "and contribution to sustainable protocol management." - ), - "prompt": ( - "As a Governance & Decentralization Specialist, evaluate the project's governance model.\n\n" - "Summary: {summary}\n" - "Stars: {star_count} | Forks: {fork_count}\n" - "Created: {created_at} | Updated: {updated_at}\n\n" - "Choose the category that best reflects its governance and decentralization approach:\n" - "{categories}\n\n" - "Respond in JSON:\n" - "{{\n" - ' "assigned_tag": "category name",\n' - ' "reason": "analysis of governance mechanisms, decentralization, and sustainability"\n' - "}}" - ), - } -] + # { + # "name": "market_strategist", + # "title": "Market Strategist", + # "description": ( + # "You focus on who the repo serves and the problem it solves. " + # "You weigh adoption potential, competitive landscape, and fit within the broader Ethereum ecosystem." + # ), + # "prompt": ( + # "You are a Market Strategist. Analyze this single repository and categorize it.\n\n" + # "Repository Summary: {summary}\n" + # "Full README Content:\n{readme_md}\n" + # "Primary Language: {language}\n" + # "Stars: {star_count} | Forks: {fork_count}\n" + # "Created: {created_at} | Updated: {updated_at}\n\n" + # "Available categories:\n" + # "{categories}\n\n" + # "CRITICAL: Respond with ONLY a single JSON object in this exact format:\n" + # "{{\n" + # ' "assigned_tag": "category name",\n' + # ' "reason": "brief market justification"\n' + # "}}\n\n" + # "Do not include any other text, explanations, or formatting. Do not mention batch processing or multiple projects." + # ) + # }, + # { + # "name": "power_user", + # "title": "Power User", + # "description": ( + # "You represent power users and developers who rely on Ethereum being awesome. " + # "You gauge ease of integration, documentation quality, and day‑to‑day usefulness." + # ), + # "prompt": ( + # "You are a Power User. Analyze this single repository and categorize it.\n\n" + # "Repository Summary: {summary}\n" + # "Full README Content:\n{readme_md}\n" + # "Primary Language: {language}\n" + # "Stars: {star_count} | Forks: {fork_count}\n" + # "Created: {created_at} | Updated: {updated_at}\n\n" + # "Available categories:\n" + # "{categories}\n\n" + # "CRITICAL: Respond with ONLY a single JSON object in this exact format:\n" + # "{{\n" + # ' "assigned_tag": "category name",\n' + # ' "reason": "brief user experience justification"\n' + # "}}\n\n" + # "Do not include any other text, explanations, or formatting. Do not mention batch processing or multiple projects." + # ) + # } +] \ No newline at end of file diff --git a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/summary_prompts.py b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/summary_prompts.py index cdd27bfb..b8128439 100644 --- a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/summary_prompts.py +++ b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/config/prompts/summary_prompts.py @@ -1,32 +1,23 @@ SUMMARY_PROMPT = ( - "You are an analyst preparing short, neutral briefs on open-source projects. " - "Read the README below and write a **concise, 2- to 3-sentence summary** that:\n" + "You are an analyst producing short, neutral briefs on Ethereum‑ecosystem open‑source projects. " + "Read the README below and write a **concise 2‑ to 3‑sentence summary** that:\n" "• states the project’s core purpose / problem it solves\n" - "• lists its main capabilities or components (1–3 key points only)\n" - "• mentions the primary intended users or systems (e.g., smart-contract developers, node operators)\n" - "• notes any strongly signalled context such as supported programming language, network, or runtime\n" + "• lists its principal capabilities or components (1 – 3 key points)\n" + "• identifies the primary intended users or systems (e.g., smart‑contract developers, node operators, rollup teams)\n" + "• notes clearly signalled context such as on‑chain layer (L1, L2, cross‑chain), domain focus (DeFi, NFTs, social, storage, etc.), " + "and prominent tech details (language, toolchain, runtime)\n" "\n" "**Style constraints**\n" - "• Use plain, factual language in third person (no hype, no marketing adjectives).\n" - "• **Do not** guess or invent details that are not explicit in the README.\n" - "• **Do not** label the project with, or copy wording from, the taxonomy below (to avoid category leakage).\n" - "• Limit the summary to <100 words; avoid bullet lists or line breaks.\n" + "• Use plain, factual third‑person language; avoid hype and marketing adjectives.\n" + "• **Do not** guess or invent information not explicit in the README.\n" + "• **Do not** label the project with, or quote wording from, the taxonomy categories (to prevent leakage).\n" + "• Keep the entire summary under 100 words with no bullet lists or extra line breaks.\n" "\n" - "Return your answer as **exactly one valid JSON object** in this form (nothing extra):\n" + "Return **exactly one valid JSON object** in this form (nothing else):\n" "{{\n" ' \"summary\": \"your summary here\"\n' "}}\n" "\n" "README:\n" "{readme_md}" -) - -TAGS_PROMPT = ( - "Based on this project summary, generate a list of relevant tags that " - "describe the project's purpose and functionality.\n\n" - "You must respond with a valid JSON object in this exact format:\n" - "{{\n" - ' "tags": ["tag1", "tag2", "tag3"]\n' - "}}\n\n" - "Summary:\n{summary}" -) +) \ No newline at end of file diff --git a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/pipeline/categorizer.py b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/pipeline/categorizer.py index 67762e9a..a465159f 100644 --- a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/pipeline/categorizer.py +++ b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/pipeline/categorizer.py @@ -96,7 +96,7 @@ def run(self, force_refresh: bool = False, target_persona_name: str = None, new_ # Prepare list of dicts, each containing summary and metadata for a project project_data_batch = [] - required_metadata_cols = ['star_count', 'fork_count', 'created_at', 'updated_at'] + required_metadata_cols = ['star_count', 'fork_count', 'language', 'created_at', 'updated_at'] for _, row in batch_df.iterrows(): project_data = { 'summary': row.get('summary', ''), diff --git a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/pipeline/unified_processor.py b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/pipeline/unified_processor.py index d669fa76..586461d0 100644 --- a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/pipeline/unified_processor.py +++ b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/pipeline/unified_processor.py @@ -58,10 +58,10 @@ def run(self, # Fetch repositories from OSO print("Fetching repositories from OSO...") - repos_df = self.fetcher.fetch_repositories(limit=limit, sort_by_stars=True) + repos_df = self.fetcher.fetch_repositories(limit=limit, sort_by_stars=True, min_stars=self.config_manager.get_min_stars()) if repos_df.empty: - print("No repositories found from OSO fetch.") + print("No repositories found from OSO fetch.") return pd.DataFrame() print(f"Found {len(repos_df)} repositories from OSO.") @@ -239,9 +239,11 @@ def _process_repositories(self, repos_df: pd.DataFrame, batch_size: int) -> pd.D # Prepare project data for categorization project_data = { 'summary': repo_data['summary'], + 'readme_md': repo_data.get('readme_md', ''), 'repo_artifact_id': repo_id, 'star_count': repo_data.get('star_count', 0), 'fork_count': repo_data.get('fork_count', 0), + 'language': repo_data.get('language', 'Unknown'), 'created_at': repo_data.get('created_at'), 'updated_at': repo_data.get('updated_at') } diff --git a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/processing/ai_service.py b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/processing/ai_service.py index 074767dd..98405d32 100644 --- a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/processing/ai_service.py +++ b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/processing/ai_service.py @@ -9,17 +9,13 @@ # Define generic type for output classes T = TypeVar( 'T', - bound=Union['SummaryOutput', 'TagsOutput', 'ClassificationOutput', 'BatchClassificationOutput'] + bound=Union['SummaryOutput', 'ClassificationOutput', 'BatchClassificationOutput'] ) @dataclass class SummaryOutput: summary: str -@dataclass -class TagsOutput: - tags: List[str] - @dataclass class ClassificationOutput: assigned_tag: str @@ -73,8 +69,6 @@ def execute_query(self, prompt: str, output_class: Type[T]) -> T: # Fallback for errors if output_class is SummaryOutput: return SummaryOutput(summary="Error generating summary.") - if output_class is TagsOutput: - return TagsOutput(tags=[]) if output_class is ClassificationOutput: return ClassificationOutput(assigned_tag="Error", reason="API call failed.") if output_class is BatchClassificationOutput: @@ -101,8 +95,6 @@ def execute_query(self, prompt: str, output_class: Type[T]) -> T: if output_class is SummaryOutput: return SummaryOutput(summary=data.get("summary", "Summary not found in response.")) - if output_class is TagsOutput: - return TagsOutput(tags=data.get("tags", [])) if output_class is ClassificationOutput: # For single classification return ClassificationOutput( assigned_tag=data.get("assigned_tag", "Other"), @@ -124,8 +116,6 @@ def execute_query(self, prompt: str, output_class: Type[T]) -> T: print(f"Error processing Gemini response: {e}. Raw text: '{response.text[:300]}...'") if output_class is SummaryOutput: return SummaryOutput(summary="Failed to parse summary from response.") - if output_class is TagsOutput: - return TagsOutput(tags=[]) if output_class is ClassificationOutput: return ClassificationOutput(assigned_tag="Other", reason="Failed to parse classification.") if output_class is BatchClassificationOutput: @@ -142,15 +132,6 @@ def make_summary(self, readme_md: str) -> SummaryOutput: prompt = prompt_template.format(readme_md=readme_md) return self.execute_query(prompt, SummaryOutput) - def make_tags(self, summary: str) -> TagsOutput: - """Generate tags for the project based on its summary.""" - if not summary or "empty repository" in summary.lower() or "error generating summary" in summary.lower(): - return TagsOutput(tags=[]) - - prompt_template = self.config_manager.get_tags_prompt_template() - prompt = prompt_template.format(summary=summary) - return self.execute_query(prompt, TagsOutput) - def classify_projects_batch_for_persona( self, project_data_batch: List[Dict[str, Any]], # Changed from summaries: List[str] @@ -196,6 +177,15 @@ def classify_projects_batch_for_persona( if not isinstance(summary_text, str): summary_text = str(summary_text) + # Ensure language is a string + language_text = project_data.get('language', "Unknown") + if not isinstance(language_text, str): + language_text = str(language_text) if language_text is not None else "Unknown" + + # Get full README content + readme_content = project_data.get('readme_md', '') + if not isinstance(readme_content, str): + readme_content = str(readme_content) if readme_content is not None else '' try: # The persona_prompt_template itself contains the persona's role description. @@ -203,6 +193,8 @@ def classify_projects_batch_for_persona( # The {categories} placeholder in the persona prompt will be filled by this categories_list_str. formatted_project_section = persona_prompt_template.format( summary=summary_text, + readme_md=readme_content, + language=language_text, star_count=formatted_star_count, fork_count=formatted_fork_count, created_at=formatted_created_at, diff --git a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/processing/fetcher.py b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/processing/fetcher.py index 36bf25ac..02edbf49 100644 --- a/experiments/ethereum-repo-clusters/ethereum-repo-clusters/processing/fetcher.py +++ b/experiments/ethereum-repo-clusters/ethereum-repo-clusters/processing/fetcher.py @@ -9,7 +9,7 @@ class DataFetcher: def __init__(self): self.oso_client = Client(api_key=OSO_API_KEY) - def fetch_repositories(self, limit: int = None, sort_by_stars: bool = True) -> pd.DataFrame: + def fetch_repositories(self, limit: int = None, sort_by_stars: bool = True, min_stars: int = 0) -> pd.DataFrame: """ Fetch repositories from OSO. @@ -28,28 +28,25 @@ def fetch_repositories(self, limit: int = None, sort_by_stars: bool = True) -> p query = f""" SELECT DISTINCT re.artifact_id AS repo_artifact_id, - p.project_id, - p.project_name, - p.display_name, re.artifact_namespace AS repo_artifact_namespace, re.artifact_name AS repo_artifact_name, re.created_at, re.updated_at, + re.language, re.star_count, re.fork_count, re.is_fork, re.num_packages_in_deps_dev FROM int_repositories_enriched AS re - JOIN projects_v1 AS p ON re.project_id = p.project_id - WHERE p.project_id IN ( + JOIN artifacts_by_project_v1 AS ap ON re.artifact_id = ap.artifact_id + WHERE ap.project_id IN ( SELECT DISTINCT project_id FROM oso.projects_by_collection_v1 WHERE {where_keywords} ) + AND re.star_count > {min_stars} """ - # The table int_superchain_s7_devtooling_repositories should have star_count - # If not, this sort will fail or do nothing. Assuming 'r.star_count' is valid. if sort_by_stars: - query += " ORDER BY re.star_count DESC, p.project_name ASC" + query += " ORDER BY re.star_count DESC, re.artifact_namespace ASC" if limit is not None and isinstance(limit, int) and limit > 0: query += f" LIMIT {limit}" diff --git a/experiments/ethereum-repo-clusters/pipeline_config.json b/experiments/ethereum-repo-clusters/pipeline_config.json index 65dc68d3..1de66d4f 100644 --- a/experiments/ethereum-repo-clusters/pipeline_config.json +++ b/experiments/ethereum-repo-clusters/pipeline_config.json @@ -1,10 +1,10 @@ { - "output_dir": "/Users/cerv1/Dropbox/Kariba/Github/insights/experiments/devtooling_labels/output", + "output_dir": "./output", "gemini_model": "gemini-2.0-flash", "summary_prompt_template": "You are an analyst preparing short, neutral briefs on open-source projects. Read the README below and write a **concise, 2- to 3-sentence summary** that:\n\u2022 states the project\u2019s core purpose / problem it solves\n\u2022 lists its main capabilities or components (1\u20133 key points only)\n\u2022 mentions the primary intended users or systems (e.g., smart-contract developers, node operators)\n\u2022 notes any strongly signalled context such as supported programming language, network, or runtime\n\n**Style constraints**\n\u2022 Use plain, factual language in third person (no hype, no marketing adjectives).\n\u2022 **Do not** guess or invent details that are not explicit in the README.\n\u2022 **Do not** label the project with, or copy wording from, the taxonomy below (to avoid category leakage).\n\u2022 Limit the summary to <100 words; avoid bullet lists or line breaks.\n\nReturn your answer as **exactly one valid JSON object** in this form (nothing extra):\n{{\n \"summary\": \"your summary here\"\n}}\n\nREADME:\n{readme_md}", - "tags_prompt_template": "Based on this project summary, generate a list of relevant tags that describe the project's purpose and functionality.\n\nYou must respond with a valid JSON object in this exact format:\n{{\n \"tags\": [\"tag1\", \"tag2\", \"tag3\"]\n}}\n\nSummary:\n{summary}", "test_mode": false, - "test_mode_limit": 30, + "test_mode_limit": 10, "batch_size_summaries": 10, - "batch_size_categorization": 10 + "batch_size_categorization": 10, + "min_stars": 9 } \ No newline at end of file diff --git a/experiments/ethereum-repo-clusters/poetry.lock b/experiments/ethereum-repo-clusters/poetry.lock new file mode 100644 index 00000000..045820c1 --- /dev/null +++ b/experiments/ethereum-repo-clusters/poetry.lock @@ -0,0 +1,1044 @@ +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. + +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[[package]] +name = "cachetools" +version = "5.5.2" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a"}, + {file = "cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4"}, +] + +[[package]] +name = "certifi" +version = "2025.6.15" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.7" +files = [ + {file = "certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057"}, + {file = "certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-win32.whl", hash = "sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-win32.whl", hash = "sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cad5f45b3146325bb38d6855642f6fd609c3f7cad4dbaf75549bf3b904d3184"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2680962a4848b3c4f155dc2ee64505a9c57186d0d56b43123b17ca3de18f0fa"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:36b31da18b8890a76ec181c3cf44326bf2c48e36d393ca1b72b3f484113ea344"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4074c5a429281bf056ddd4c5d3b740ebca4d43ffffe2ef4bf4d2d05114299da"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9e36a97bee9b86ef9a1cf7bb96747eb7a15c2f22bdb5b516434b00f2a599f02"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:1b1bde144d98e446b056ef98e59c256e9294f6b74d7af6846bf5ffdafd687a7d"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:915f3849a011c1f593ab99092f3cecfcb4d65d8feb4a64cf1bf2d22074dc0ec4"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:fb707f3e15060adf5b7ada797624a6c6e0138e2a26baa089df64c68ee98e040f"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:25a23ea5c7edc53e0f29bae2c44fcb5a1aa10591aae107f2a2b2583a9c5cbc64"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:770cab594ecf99ae64c236bc9ee3439c3f46be49796e265ce0cc8bc17b10294f"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-win32.whl", hash = "sha256:6a0289e4589e8bdfef02a80478f1dfcb14f0ab696b5a00e1f4b8a14a307a3c58"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6fc1f5b51fa4cecaa18f2bd7a003f3dd039dd615cd69a2afd6d3b19aed6775f2"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76af085e67e56c8816c3ccf256ebd136def2ed9654525348cfa744b6802b69eb"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e45ba65510e2647721e35323d6ef54c7974959f6081b58d4ef5d87c60c84919a"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:046595208aae0120559a67693ecc65dd75d46f7bf687f159127046628178dc45"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75d10d37a47afee94919c4fab4c22b9bc2a8bf7d4f46f87363bcf0573f3ff4f5"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6333b3aa5a12c26b2a4d4e7335a28f1475e0e5e17d69d55141ee3cab736f66d1"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8323a9b031aa0393768b87f04b4164a40037fb2a3c11ac06a03ffecd3618027"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:24498ba8ed6c2e0b56d4acbf83f2d989720a93b41d712ebd4f4979660db4417b"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:844da2b5728b5ce0e32d863af26f32b5ce61bc4273a9c720a9f3aa9df73b1455"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:65c981bdbd3f57670af8b59777cbfae75364b483fa8a9f420f08094531d54a01"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:3c21d4fca343c805a52c0c78edc01e3477f6dd1ad7c47653241cf2a206d4fc58"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:dc7039885fa1baf9be153a0626e337aa7ec8bf96b0128605fb0d77788ddc1681"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-win32.whl", hash = "sha256:8272b73e1c5603666618805fe821edba66892e2870058c94c53147602eab29c7"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:70f7172939fdf8790425ba31915bfbe8335030f05b9913d7ae00a87d4395620a"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e92fca20c46e9f5e1bb485887d074918b13543b1c2a1185e69bb8d17ab6236a7"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50bf98d5e563b83cc29471fa114366e6806bc06bc7a25fd59641e41445327836"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:721c76e84fe669be19c5791da68232ca2e05ba5185575086e384352e2c309597"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d8fd25b7f4675d0c47cf95b594d4e7b158aca33b76aa63d07186e13c0e0ab7"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3daeac64d5b371dea99714f08ffc2c208522ec6b06fbc7866a450dd446f5c0f"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dccab8d5fa1ef9bfba0590ecf4d46df048d18ffe3eec01eeb73a42e0d9e7a8ba"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:aaf27faa992bfee0264dc1f03f4c75e9fcdda66a519db6b957a3f826e285cf12"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:eb30abc20df9ab0814b5a2524f23d75dcf83cde762c161917a2b4b7b55b1e518"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c72fbbe68c6f32f251bdc08b8611c7b3060612236e960ef848e0a517ddbe76c5"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:982bb1e8b4ffda883b3d0a521e23abcd6fd17418f6d2c4118d257a10199c0ce3"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-win32.whl", hash = "sha256:43e0933a0eff183ee85833f341ec567c0980dae57c464d8a508e1b2ceb336471"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:d11b54acf878eef558599658b0ffca78138c8c3655cf4f3a4a673c437e67732e"}, + {file = "charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0"}, + {file = "charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63"}, +] + +[[package]] +name = "click" +version = "8.2.1" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.10" +files = [ + {file = "click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b"}, + {file = "click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "google-ai-generativelanguage" +version = "0.6.15" +description = "Google Ai Generativelanguage API client library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google_ai_generativelanguage-0.6.15-py3-none-any.whl", hash = "sha256:5a03ef86377aa184ffef3662ca28f19eeee158733e45d7947982eb953c6ebb6c"}, + {file = "google_ai_generativelanguage-0.6.15.tar.gz", hash = "sha256:8f6d9dc4c12b065fe2d0289026171acea5183ebf2d0b11cefe12f3821e159ec3"}, +] + +[package.dependencies] +google-api-core = {version = ">=1.34.1,<2.0.dev0 || >=2.11.dev0,<3.0.0dev", extras = ["grpc"]} +google-auth = ">=2.14.1,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0dev" +proto-plus = [ + {version = ">=1.22.3,<2.0.0dev", markers = "python_version < \"3.13\""}, + {version = ">=1.25.0,<2.0.0dev", markers = "python_version >= \"3.13\""}, +] +protobuf = ">=3.20.2,<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,<6.0.0dev" + +[[package]] +name = "google-api-core" +version = "2.25.1" +description = "Google API client core library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google_api_core-2.25.1-py3-none-any.whl", hash = "sha256:8a2a56c1fef82987a524371f99f3bd0143702fecc670c72e600c1cda6bf8dbb7"}, + {file = "google_api_core-2.25.1.tar.gz", hash = "sha256:d2aaa0b13c78c61cb3f4282c464c046e45fbd75755683c9c525e6e8f7ed0a5e8"}, +] + +[package.dependencies] +google-auth = ">=2.14.1,<3.0.0" +googleapis-common-protos = ">=1.56.2,<2.0.0" +grpcio = {version = ">=1.49.1,<2.0.0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""} +grpcio-status = {version = ">=1.49.1,<2.0.0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""} +proto-plus = [ + {version = ">=1.22.3,<2.0.0", markers = "python_version < \"3.13\""}, + {version = ">=1.25.0,<2.0.0", markers = "python_version >= \"3.13\""}, +] +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,<7.0.0" +requests = ">=2.18.0,<3.0.0" + +[package.extras] +async-rest = ["google-auth[aiohttp] (>=2.35.0,<3.0.0)"] +grpc = ["grpcio (>=1.33.2,<2.0.0)", "grpcio (>=1.49.1,<2.0.0)", "grpcio-status (>=1.33.2,<2.0.0)", "grpcio-status (>=1.49.1,<2.0.0)"] +grpcgcp = ["grpcio-gcp (>=0.2.2,<1.0.0)"] +grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.0)"] + +[[package]] +name = "google-api-python-client" +version = "2.174.0" +description = "Google API Client Library for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google_api_python_client-2.174.0-py3-none-any.whl", hash = "sha256:f695205ceec97bfaa1590a14282559c4109326c473b07352233a3584cdbf4b89"}, + {file = "google_api_python_client-2.174.0.tar.gz", hash = "sha256:9eb7616a820b38a9c12c5486f9b9055385c7feb18b20cbafc5c5a688b14f3515"}, +] + +[package.dependencies] +google-api-core = ">=1.31.5,<2.0.dev0 || >2.3.0,<3.0.0" +google-auth = ">=1.32.0,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0" +google-auth-httplib2 = ">=0.2.0,<1.0.0" +httplib2 = ">=0.19.0,<1.0.0" +uritemplate = ">=3.0.1,<5" + +[[package]] +name = "google-auth" +version = "2.40.3" +description = "Google Authentication Library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google_auth-2.40.3-py2.py3-none-any.whl", hash = "sha256:1370d4593e86213563547f97a92752fc658456fe4514c809544f330fed45a7ca"}, + {file = "google_auth-2.40.3.tar.gz", hash = "sha256:500c3a29adedeb36ea9cf24b8d10858e152f2412e3ca37829b3fa18e33d63b77"}, +] + +[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)", "requests (>=2.20.0,<3.0.0)"] +enterprise-cert = ["cryptography", "pyopenssl"] +pyjwt = ["cryptography (<39.0.0)", "cryptography (>=38.0.3)", "pyjwt (>=2.0)"] +pyopenssl = ["cryptography (<39.0.0)", "cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] +reauth = ["pyu2f (>=0.1.5)"] +requests = ["requests (>=2.20.0,<3.0.0)"] +testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.6.2,<4.0.0)", "aioresponses", "cryptography (<39.0.0)", "cryptography (>=38.0.3)", "flask", "freezegun", "grpcio", "mock", "oauth2client", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"] +urllib3 = ["packaging", "urllib3"] + +[[package]] +name = "google-auth-httplib2" +version = "0.2.0" +description = "Google Authentication Library: httplib2 transport" +optional = false +python-versions = "*" +files = [ + {file = "google-auth-httplib2-0.2.0.tar.gz", hash = "sha256:38aa7badf48f974f1eb9861794e9c0cb2a0511a4ec0679b1f886d108f5640e05"}, + {file = "google_auth_httplib2-0.2.0-py2.py3-none-any.whl", hash = "sha256:b65a0a2123300dd71281a7bf6e64d65a0759287df52729bdd1ae2e47dc311a3d"}, +] + +[package.dependencies] +google-auth = "*" +httplib2 = ">=0.19.0" + +[[package]] +name = "google-generativeai" +version = "0.8.5" +description = "Google Generative AI High level API client library and tools." +optional = false +python-versions = ">=3.9" +files = [ + {file = "google_generativeai-0.8.5-py3-none-any.whl", hash = "sha256:22b420817fb263f8ed520b33285f45976d5b21e904da32b80d4fd20c055123a2"}, +] + +[package.dependencies] +google-ai-generativelanguage = "0.6.15" +google-api-core = "*" +google-api-python-client = "*" +google-auth = ">=2.15.0" +protobuf = "*" +pydantic = "*" +tqdm = "*" +typing-extensions = "*" + +[package.extras] +dev = ["Pillow", "absl-py", "black", "ipython", "nose2", "pandas", "pytype", "pyyaml"] + +[[package]] +name = "googleapis-common-protos" +version = "1.70.0" +description = "Common protobufs used in Google APIs" +optional = false +python-versions = ">=3.7" +files = [ + {file = "googleapis_common_protos-1.70.0-py3-none-any.whl", hash = "sha256:b8bfcca8c25a2bb253e0e0b0adaf8c00773e5e6af6fd92397576680b807e0fd8"}, + {file = "googleapis_common_protos-1.70.0.tar.gz", hash = "sha256:0e1b44e0ea153e6594f9f394fef15193a68aaaea2d843f83e2742717ca753257"}, +] + +[package.dependencies] +protobuf = ">=3.20.2,<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,<7.0.0" + +[package.extras] +grpc = ["grpcio (>=1.44.0,<2.0.0)"] + +[[package]] +name = "grpcio" +version = "1.73.1" +description = "HTTP/2-based RPC framework" +optional = false +python-versions = ">=3.9" +files = [ + {file = "grpcio-1.73.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:2d70f4ddd0a823436c2624640570ed6097e40935c9194482475fe8e3d9754d55"}, + {file = "grpcio-1.73.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:3841a8a5a66830261ab6a3c2a3dc539ed84e4ab019165f77b3eeb9f0ba621f26"}, + {file = "grpcio-1.73.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:628c30f8e77e0258ab788750ec92059fc3d6628590fb4b7cea8c102503623ed7"}, + {file = "grpcio-1.73.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:67a0468256c9db6d5ecb1fde4bf409d016f42cef649323f0a08a72f352d1358b"}, + {file = "grpcio-1.73.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68b84d65bbdebd5926eb5c53b0b9ec3b3f83408a30e4c20c373c5337b4219ec5"}, + {file = "grpcio-1.73.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c54796ca22b8349cc594d18b01099e39f2b7ffb586ad83217655781a350ce4da"}, + {file = "grpcio-1.73.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:75fc8e543962ece2f7ecd32ada2d44c0c8570ae73ec92869f9af8b944863116d"}, + {file = "grpcio-1.73.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6a6037891cd2b1dd1406b388660522e1565ed340b1fea2955b0234bdd941a862"}, + {file = "grpcio-1.73.1-cp310-cp310-win32.whl", hash = "sha256:cce7265b9617168c2d08ae570fcc2af4eaf72e84f8c710ca657cc546115263af"}, + {file = "grpcio-1.73.1-cp310-cp310-win_amd64.whl", hash = "sha256:6a2b372e65fad38842050943f42ce8fee00c6f2e8ea4f7754ba7478d26a356ee"}, + {file = "grpcio-1.73.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:ba2cea9f7ae4bc21f42015f0ec98f69ae4179848ad744b210e7685112fa507a1"}, + {file = "grpcio-1.73.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:d74c3f4f37b79e746271aa6cdb3a1d7e4432aea38735542b23adcabaaee0c097"}, + {file = "grpcio-1.73.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:5b9b1805a7d61c9e90541cbe8dfe0a593dfc8c5c3a43fe623701b6a01b01d710"}, + {file = "grpcio-1.73.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3215f69a0670a8cfa2ab53236d9e8026bfb7ead5d4baabe7d7dc11d30fda967"}, + {file = "grpcio-1.73.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc5eccfd9577a5dc7d5612b2ba90cca4ad14c6d949216c68585fdec9848befb1"}, + {file = "grpcio-1.73.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dc7d7fd520614fce2e6455ba89791458020a39716951c7c07694f9dbae28e9c0"}, + {file = "grpcio-1.73.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:105492124828911f85127e4825d1c1234b032cb9d238567876b5515d01151379"}, + {file = "grpcio-1.73.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:610e19b04f452ba6f402ac9aa94eb3d21fbc94553368008af634812c4a85a99e"}, + {file = "grpcio-1.73.1-cp311-cp311-win32.whl", hash = "sha256:d60588ab6ba0ac753761ee0e5b30a29398306401bfbceffe7d68ebb21193f9d4"}, + {file = "grpcio-1.73.1-cp311-cp311-win_amd64.whl", hash = "sha256:6957025a4608bb0a5ff42abd75bfbb2ed99eda29d5992ef31d691ab54b753643"}, + {file = "grpcio-1.73.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:921b25618b084e75d424a9f8e6403bfeb7abef074bb6c3174701e0f2542debcf"}, + {file = "grpcio-1.73.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:277b426a0ed341e8447fbf6c1d6b68c952adddf585ea4685aa563de0f03df887"}, + {file = "grpcio-1.73.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:96c112333309493c10e118d92f04594f9055774757f5d101b39f8150f8c25582"}, + {file = "grpcio-1.73.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f48e862aed925ae987eb7084409a80985de75243389dc9d9c271dd711e589918"}, + {file = "grpcio-1.73.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83a6c2cce218e28f5040429835fa34a29319071079e3169f9543c3fbeff166d2"}, + {file = "grpcio-1.73.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:65b0458a10b100d815a8426b1442bd17001fdb77ea13665b2f7dc9e8587fdc6b"}, + {file = "grpcio-1.73.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0a9f3ea8dce9eae9d7cb36827200133a72b37a63896e0e61a9d5ec7d61a59ab1"}, + {file = "grpcio-1.73.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:de18769aea47f18e782bf6819a37c1c528914bfd5683b8782b9da356506190c8"}, + {file = "grpcio-1.73.1-cp312-cp312-win32.whl", hash = "sha256:24e06a5319e33041e322d32c62b1e728f18ab8c9dbc91729a3d9f9e3ed336642"}, + {file = "grpcio-1.73.1-cp312-cp312-win_amd64.whl", hash = "sha256:303c8135d8ab176f8038c14cc10d698ae1db9c480f2b2823f7a987aa2a4c5646"}, + {file = "grpcio-1.73.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:b310824ab5092cf74750ebd8a8a8981c1810cb2b363210e70d06ef37ad80d4f9"}, + {file = "grpcio-1.73.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:8f5a6df3fba31a3485096ac85b2e34b9666ffb0590df0cd044f58694e6a1f6b5"}, + {file = "grpcio-1.73.1-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:052e28fe9c41357da42250a91926a3e2f74c046575c070b69659467ca5aa976b"}, + {file = "grpcio-1.73.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c0bf15f629b1497436596b1cbddddfa3234273490229ca29561209778ebe182"}, + {file = "grpcio-1.73.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ab860d5bfa788c5a021fba264802e2593688cd965d1374d31d2b1a34cacd854"}, + {file = "grpcio-1.73.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:ad1d958c31cc91ab050bd8a91355480b8e0683e21176522bacea225ce51163f2"}, + {file = "grpcio-1.73.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:f43ffb3bd415c57224c7427bfb9e6c46a0b6e998754bfa0d00f408e1873dcbb5"}, + {file = "grpcio-1.73.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:686231cdd03a8a8055f798b2b54b19428cdf18fa1549bee92249b43607c42668"}, + {file = "grpcio-1.73.1-cp313-cp313-win32.whl", hash = "sha256:89018866a096e2ce21e05eabed1567479713ebe57b1db7cbb0f1e3b896793ba4"}, + {file = "grpcio-1.73.1-cp313-cp313-win_amd64.whl", hash = "sha256:4a68f8c9966b94dff693670a5cf2b54888a48a5011c5d9ce2295a1a1465ee84f"}, + {file = "grpcio-1.73.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:b4adc97d2d7f5c660a5498bda978ebb866066ad10097265a5da0511323ae9f50"}, + {file = "grpcio-1.73.1-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:c45a28a0cfb6ddcc7dc50a29de44ecac53d115c3388b2782404218db51cb2df3"}, + {file = "grpcio-1.73.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:10af9f2ab98a39f5b6c1896c6fc2036744b5b41d12739d48bed4c3e15b6cf900"}, + {file = "grpcio-1.73.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:45cf17dcce5ebdb7b4fe9e86cb338fa99d7d1bb71defc78228e1ddf8d0de8cbb"}, + {file = "grpcio-1.73.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c502c2e950fc7e8bf05c047e8a14522ef7babac59abbfde6dbf46b7a0d9c71e"}, + {file = "grpcio-1.73.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6abfc0f9153dc4924536f40336f88bd4fe7bd7494f028675e2e04291b8c2c62a"}, + {file = "grpcio-1.73.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ed451a0e39c8e51eb1612b78686839efd1a920666d1666c1adfdb4fd51680c0f"}, + {file = "grpcio-1.73.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:07f08705a5505c9b5b0cbcbabafb96462b5a15b7236bbf6bbcc6b0b91e1cbd7e"}, + {file = "grpcio-1.73.1-cp39-cp39-win32.whl", hash = "sha256:ad5c958cc3d98bb9d71714dc69f1c13aaf2f4b53e29d4cc3f1501ef2e4d129b2"}, + {file = "grpcio-1.73.1-cp39-cp39-win_amd64.whl", hash = "sha256:42f0660bce31b745eb9d23f094a332d31f210dcadd0fc8e5be7e4c62a87ce86b"}, + {file = "grpcio-1.73.1.tar.gz", hash = "sha256:7fce2cd1c0c1116cf3850564ebfc3264fba75d3c74a7414373f1238ea365ef87"}, +] + +[package.extras] +protobuf = ["grpcio-tools (>=1.73.1)"] + +[[package]] +name = "grpcio-status" +version = "1.71.2" +description = "Status proto mapping for gRPC" +optional = false +python-versions = ">=3.9" +files = [ + {file = "grpcio_status-1.71.2-py3-none-any.whl", hash = "sha256:803c98cb6a8b7dc6dbb785b1111aed739f241ab5e9da0bba96888aa74704cfd3"}, + {file = "grpcio_status-1.71.2.tar.gz", hash = "sha256:c7a97e176df71cdc2c179cd1847d7fc86cca5832ad12e9798d7fed6b7a1aab50"}, +] + +[package.dependencies] +googleapis-common-protos = ">=1.5.5" +grpcio = ">=1.71.2" +protobuf = ">=5.26.1,<6.0dev" + +[[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.10" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + +[[package]] +name = "numpy" +version = "2.3.1" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.11" +files = [ + {file = "numpy-2.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6ea9e48336a402551f52cd8f593343699003d2353daa4b72ce8d34f66b722070"}, + {file = "numpy-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ccb7336eaf0e77c1635b232c141846493a588ec9ea777a7c24d7166bb8533ae"}, + {file = "numpy-2.3.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0bb3a4a61e1d327e035275d2a993c96fa786e4913aa089843e6a2d9dd205c66a"}, + {file = "numpy-2.3.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:e344eb79dab01f1e838ebb67aab09965fb271d6da6b00adda26328ac27d4a66e"}, + {file = "numpy-2.3.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:467db865b392168ceb1ef1ffa6f5a86e62468c43e0cfb4ab6da667ede10e58db"}, + {file = "numpy-2.3.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:afed2ce4a84f6b0fc6c1ce734ff368cbf5a5e24e8954a338f3bdffa0718adffb"}, + {file = "numpy-2.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0025048b3c1557a20bc80d06fdeb8cc7fc193721484cca82b2cfa072fec71a93"}, + {file = "numpy-2.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a5ee121b60aa509679b682819c602579e1df14a5b07fe95671c8849aad8f2115"}, + {file = "numpy-2.3.1-cp311-cp311-win32.whl", hash = "sha256:a8b740f5579ae4585831b3cf0e3b0425c667274f82a484866d2adf9570539369"}, + {file = "numpy-2.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4580adadc53311b163444f877e0789f1c8861e2698f6b2a4ca852fda154f3ff"}, + {file = "numpy-2.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:ec0bdafa906f95adc9a0c6f26a4871fa753f25caaa0e032578a30457bff0af6a"}, + {file = "numpy-2.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2959d8f268f3d8ee402b04a9ec4bb7604555aeacf78b360dc4ec27f1d508177d"}, + {file = "numpy-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:762e0c0c6b56bdedfef9a8e1d4538556438288c4276901ea008ae44091954e29"}, + {file = "numpy-2.3.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:867ef172a0976aaa1f1d1b63cf2090de8b636a7674607d514505fb7276ab08fc"}, + {file = "numpy-2.3.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:4e602e1b8682c2b833af89ba641ad4176053aaa50f5cacda1a27004352dde943"}, + {file = "numpy-2.3.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:8e333040d069eba1652fb08962ec5b76af7f2c7bce1df7e1418c8055cf776f25"}, + {file = "numpy-2.3.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:e7cbf5a5eafd8d230a3ce356d892512185230e4781a361229bd902ff403bc660"}, + {file = "numpy-2.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5f1b8f26d1086835f442286c1d9b64bb3974b0b1e41bb105358fd07d20872952"}, + {file = "numpy-2.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ee8340cb48c9b7a5899d1149eece41ca535513a9698098edbade2a8e7a84da77"}, + {file = "numpy-2.3.1-cp312-cp312-win32.whl", hash = "sha256:e772dda20a6002ef7061713dc1e2585bc1b534e7909b2030b5a46dae8ff077ab"}, + {file = "numpy-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:cfecc7822543abdea6de08758091da655ea2210b8ffa1faf116b940693d3df76"}, + {file = "numpy-2.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:7be91b2239af2658653c5bb6f1b8bccafaf08226a258caf78ce44710a0160d30"}, + {file = "numpy-2.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25a1992b0a3fdcdaec9f552ef10d8103186f5397ab45e2d25f8ac51b1a6b97e8"}, + {file = "numpy-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7dea630156d39b02a63c18f508f85010230409db5b2927ba59c8ba4ab3e8272e"}, + {file = "numpy-2.3.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:bada6058dd886061f10ea15f230ccf7dfff40572e99fef440a4a857c8728c9c0"}, + {file = "numpy-2.3.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:a894f3816eb17b29e4783e5873f92faf55b710c2519e5c351767c51f79d8526d"}, + {file = "numpy-2.3.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:18703df6c4a4fee55fd3d6e5a253d01c5d33a295409b03fda0c86b3ca2ff41a1"}, + {file = "numpy-2.3.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:5902660491bd7a48b2ec16c23ccb9124b8abfd9583c5fdfa123fe6b421e03de1"}, + {file = "numpy-2.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:36890eb9e9d2081137bd78d29050ba63b8dab95dff7912eadf1185e80074b2a0"}, + {file = "numpy-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a780033466159c2270531e2b8ac063704592a0bc62ec4a1b991c7c40705eb0e8"}, + {file = "numpy-2.3.1-cp313-cp313-win32.whl", hash = "sha256:39bff12c076812595c3a306f22bfe49919c5513aa1e0e70fac756a0be7c2a2b8"}, + {file = "numpy-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d5ee6eec45f08ce507a6570e06f2f879b374a552087a4179ea7838edbcbfa42"}, + {file = "numpy-2.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:0c4d9e0a8368db90f93bd192bfa771ace63137c3488d198ee21dfb8e7771916e"}, + {file = "numpy-2.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:b0b5397374f32ec0649dd98c652a1798192042e715df918c20672c62fb52d4b8"}, + {file = "numpy-2.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c5bdf2015ccfcee8253fb8be695516ac4457c743473a43290fd36eba6a1777eb"}, + {file = "numpy-2.3.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d70f20df7f08b90a2062c1f07737dd340adccf2068d0f1b9b3d56e2038979fee"}, + {file = "numpy-2.3.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:2fb86b7e58f9ac50e1e9dd1290154107e47d1eef23a0ae9145ded06ea606f992"}, + {file = "numpy-2.3.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:23ab05b2d241f76cb883ce8b9a93a680752fbfcbd51c50eff0b88b979e471d8c"}, + {file = "numpy-2.3.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:ce2ce9e5de4703a673e705183f64fd5da5bf36e7beddcb63a25ee2286e71ca48"}, + {file = "numpy-2.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c4913079974eeb5c16ccfd2b1f09354b8fed7e0d6f2cab933104a09a6419b1ee"}, + {file = "numpy-2.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:010ce9b4f00d5c036053ca684c77441f2f2c934fd23bee058b4d6f196efd8280"}, + {file = "numpy-2.3.1-cp313-cp313t-win32.whl", hash = "sha256:6269b9edfe32912584ec496d91b00b6d34282ca1d07eb10e82dfc780907d6c2e"}, + {file = "numpy-2.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:2a809637460e88a113e186e87f228d74ae2852a2e0c44de275263376f17b5bdc"}, + {file = "numpy-2.3.1-cp313-cp313t-win_arm64.whl", hash = "sha256:eccb9a159db9aed60800187bc47a6d3451553f0e1b08b068d8b277ddfbb9b244"}, + {file = "numpy-2.3.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ad506d4b09e684394c42c966ec1527f6ebc25da7f4da4b1b056606ffe446b8a3"}, + {file = "numpy-2.3.1-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:ebb8603d45bc86bbd5edb0d63e52c5fd9e7945d3a503b77e486bd88dde67a19b"}, + {file = "numpy-2.3.1-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:15aa4c392ac396e2ad3d0a2680c0f0dee420f9fed14eef09bdb9450ee6dcb7b7"}, + {file = "numpy-2.3.1-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c6e0bf9d1a2f50d2b65a7cf56db37c095af17b59f6c132396f7c6d5dd76484df"}, + {file = "numpy-2.3.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:eabd7e8740d494ce2b4ea0ff05afa1b7b291e978c0ae075487c51e8bd93c0c68"}, + {file = "numpy-2.3.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:e610832418a2bc09d974cc9fecebfa51e9532d6190223bc5ef6a7402ebf3b5cb"}, + {file = "numpy-2.3.1.tar.gz", hash = "sha256:1ec9ae20a4226da374362cca3c62cd753faf2f951440b0e3b98e93c235441d2b"}, +] + +[[package]] +name = "pandas" +version = "2.3.0" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:625466edd01d43b75b1883a64d859168e4556261a5035b32f9d743b67ef44634"}, + {file = "pandas-2.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a6872d695c896f00df46b71648eea332279ef4077a409e2fe94220208b6bb675"}, + {file = "pandas-2.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4dd97c19bd06bc557ad787a15b6489d2614ddaab5d104a0310eb314c724b2d2"}, + {file = "pandas-2.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:034abd6f3db8b9880aaee98f4f5d4dbec7c4829938463ec046517220b2f8574e"}, + {file = "pandas-2.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23c2b2dc5213810208ca0b80b8666670eb4660bbfd9d45f58592cc4ddcfd62e1"}, + {file = "pandas-2.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:39ff73ec07be5e90330cc6ff5705c651ace83374189dcdcb46e6ff54b4a72cd6"}, + {file = "pandas-2.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:40cecc4ea5abd2921682b57532baea5588cc5f80f0231c624056b146887274d2"}, + {file = "pandas-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8adff9f138fc614347ff33812046787f7d43b3cef7c0f0171b3340cae333f6ca"}, + {file = "pandas-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e5f08eb9a445d07720776df6e641975665c9ea12c9d8a331e0f6890f2dcd76ef"}, + {file = "pandas-2.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa35c266c8cd1a67d75971a1912b185b492d257092bdd2709bbdebe574ed228d"}, + {file = "pandas-2.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14a0cc77b0f089d2d2ffe3007db58f170dae9b9f54e569b299db871a3ab5bf46"}, + {file = "pandas-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c06f6f144ad0a1bf84699aeea7eff6068ca5c63ceb404798198af7eb86082e33"}, + {file = "pandas-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ed16339bc354a73e0a609df36d256672c7d296f3f767ac07257801aa064ff73c"}, + {file = "pandas-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:fa07e138b3f6c04addfeaf56cc7fdb96c3b68a3fe5e5401251f231fce40a0d7a"}, + {file = "pandas-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2eb4728a18dcd2908c7fccf74a982e241b467d178724545a48d0caf534b38ebf"}, + {file = "pandas-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b9d8c3187be7479ea5c3d30c32a5d73d62a621166675063b2edd21bc47614027"}, + {file = "pandas-2.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ff730713d4c4f2f1c860e36c005c7cefc1c7c80c21c0688fd605aa43c9fcf09"}, + {file = "pandas-2.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba24af48643b12ffe49b27065d3babd52702d95ab70f50e1b34f71ca703e2c0d"}, + {file = "pandas-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:404d681c698e3c8a40a61d0cd9412cc7364ab9a9cc6e144ae2992e11a2e77a20"}, + {file = "pandas-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6021910b086b3ca756755e86ddc64e0ddafd5e58e076c72cb1585162e5ad259b"}, + {file = "pandas-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:094e271a15b579650ebf4c5155c05dcd2a14fd4fdd72cf4854b2f7ad31ea30be"}, + {file = "pandas-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c7e2fc25f89a49a11599ec1e76821322439d90820108309bf42130d2f36c983"}, + {file = "pandas-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c6da97aeb6a6d233fb6b17986234cc723b396b50a3c6804776351994f2a658fd"}, + {file = "pandas-2.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb32dc743b52467d488e7a7c8039b821da2826a9ba4f85b89ea95274f863280f"}, + {file = "pandas-2.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:213cd63c43263dbb522c1f8a7c9d072e25900f6975596f883f4bebd77295d4f3"}, + {file = "pandas-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1d2b33e68d0ce64e26a4acc2e72d747292084f4e8db4c847c6f5f6cbe56ed6d8"}, + {file = "pandas-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:430a63bae10b5086995db1b02694996336e5a8ac9a96b4200572b413dfdfccb9"}, + {file = "pandas-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:4930255e28ff5545e2ca404637bcc56f031893142773b3468dc021c6c32a1390"}, + {file = "pandas-2.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f925f1ef673b4bd0271b1809b72b3270384f2b7d9d14a189b12b7fc02574d575"}, + {file = "pandas-2.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78ad363ddb873a631e92a3c063ade1ecfb34cae71e9a2be6ad100f875ac1042"}, + {file = "pandas-2.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:951805d146922aed8357e4cc5671b8b0b9be1027f0619cea132a9f3f65f2f09c"}, + {file = "pandas-2.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a881bc1309f3fce34696d07b00f13335c41f5f5a8770a33b09ebe23261cfc67"}, + {file = "pandas-2.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e1991bbb96f4050b09b5f811253c4f3cf05ee89a589379aa36cd623f21a31d6f"}, + {file = "pandas-2.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bb3be958022198531eb7ec2008cfc78c5b1eed51af8600c6c5d9160d89d8d249"}, + {file = "pandas-2.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9efc0acbbffb5236fbdf0409c04edce96bec4bdaa649d49985427bd1ec73e085"}, + {file = "pandas-2.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:75651c14fde635e680496148a8526b328e09fe0572d9ae9b638648c46a544ba3"}, + {file = "pandas-2.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5be867a0541a9fb47a4be0c5790a4bccd5b77b92f0a59eeec9375fafc2aa14"}, + {file = "pandas-2.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84141f722d45d0c2a89544dd29d35b3abfc13d2250ed7e68394eda7564bd6324"}, + {file = "pandas-2.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f95a2aef32614ed86216d3c450ab12a4e82084e8102e355707a1d96e33d51c34"}, + {file = "pandas-2.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e0f51973ba93a9f97185049326d75b942b9aeb472bec616a129806facb129ebb"}, + {file = "pandas-2.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:b198687ca9c8529662213538a9bb1e60fa0bf0f6af89292eb68fea28743fcd5a"}, + {file = "pandas-2.3.0.tar.gz", hash = "sha256:34600ab34ebf1131a7613a260a61dbe8b62c188ec0ea4c296da7c9a06b004133"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + +[[package]] +name = "proto-plus" +version = "1.26.1" +description = "Beautiful, Pythonic protocol buffers" +optional = false +python-versions = ">=3.7" +files = [ + {file = "proto_plus-1.26.1-py3-none-any.whl", hash = "sha256:13285478c2dcf2abb829db158e1047e2f1e8d63a077d94263c2b88b043c75a66"}, + {file = "proto_plus-1.26.1.tar.gz", hash = "sha256:21a515a4c4c0088a773899e23c7bbade3d18f9c66c73edd4c7ee3816bc96a012"}, +] + +[package.dependencies] +protobuf = ">=3.19.0,<7.0.0" + +[package.extras] +testing = ["google-api-core (>=1.31.5)"] + +[[package]] +name = "protobuf" +version = "5.29.5" +description = "" +optional = false +python-versions = ">=3.8" +files = [ + {file = "protobuf-5.29.5-cp310-abi3-win32.whl", hash = "sha256:3f1c6468a2cfd102ff4703976138844f78ebd1fb45f49011afc5139e9e283079"}, + {file = "protobuf-5.29.5-cp310-abi3-win_amd64.whl", hash = "sha256:3f76e3a3675b4a4d867b52e4a5f5b78a2ef9565549d4037e06cf7b0942b1d3fc"}, + {file = "protobuf-5.29.5-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e38c5add5a311f2a6eb0340716ef9b039c1dfa428b28f25a7838ac329204a671"}, + {file = "protobuf-5.29.5-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:fa18533a299d7ab6c55a238bf8629311439995f2e7eca5caaff08663606e9015"}, + {file = "protobuf-5.29.5-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:63848923da3325e1bf7e9003d680ce6e14b07e55d0473253a690c3a8b8fd6e61"}, + {file = "protobuf-5.29.5-cp38-cp38-win32.whl", hash = "sha256:ef91363ad4faba7b25d844ef1ada59ff1604184c0bcd8b39b8a6bef15e1af238"}, + {file = "protobuf-5.29.5-cp38-cp38-win_amd64.whl", hash = "sha256:7318608d56b6402d2ea7704ff1e1e4597bee46d760e7e4dd42a3d45e24b87f2e"}, + {file = "protobuf-5.29.5-cp39-cp39-win32.whl", hash = "sha256:6f642dc9a61782fa72b90878af134c5afe1917c89a568cd3476d758d3c3a0736"}, + {file = "protobuf-5.29.5-cp39-cp39-win_amd64.whl", hash = "sha256:470f3af547ef17847a28e1f47200a1cbf0ba3ff57b7de50d22776607cd2ea353"}, + {file = "protobuf-5.29.5-py3-none-any.whl", hash = "sha256:6cf42630262c59b2d8de33954443d94b746c952b01434fc58a417fdbd2e84bd5"}, + {file = "protobuf-5.29.5.tar.gz", hash = "sha256:bc1463bafd4b0929216c35f437a8e28731a2b7fe3d98bb77a600efced5a15c84"}, +] + +[[package]] +name = "pyarrow" +version = "20.0.0" +description = "Python library for Apache Arrow" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pyarrow-20.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:c7dd06fd7d7b410ca5dc839cc9d485d2bc4ae5240851bcd45d85105cc90a47d7"}, + {file = "pyarrow-20.0.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:d5382de8dc34c943249b01c19110783d0d64b207167c728461add1ecc2db88e4"}, + {file = "pyarrow-20.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6415a0d0174487456ddc9beaead703d0ded5966129fa4fd3114d76b5d1c5ceae"}, + {file = "pyarrow-20.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15aa1b3b2587e74328a730457068dc6c89e6dcbf438d4369f572af9d320a25ee"}, + {file = "pyarrow-20.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:5605919fbe67a7948c1f03b9f3727d82846c053cd2ce9303ace791855923fd20"}, + {file = "pyarrow-20.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a5704f29a74b81673d266e5ec1fe376f060627c2e42c5c7651288ed4b0db29e9"}, + {file = "pyarrow-20.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:00138f79ee1b5aca81e2bdedb91e3739b987245e11fa3c826f9e57c5d102fb75"}, + {file = "pyarrow-20.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f2d67ac28f57a362f1a2c1e6fa98bfe2f03230f7e15927aecd067433b1e70ce8"}, + {file = "pyarrow-20.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:4a8b029a07956b8d7bd742ffca25374dd3f634b35e46cc7a7c3fa4c75b297191"}, + {file = "pyarrow-20.0.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:24ca380585444cb2a31324c546a9a56abbe87e26069189e14bdba19c86c049f0"}, + {file = "pyarrow-20.0.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:95b330059ddfdc591a3225f2d272123be26c8fa76e8c9ee1a77aad507361cfdb"}, + {file = "pyarrow-20.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f0fb1041267e9968c6d0d2ce3ff92e3928b243e2b6d11eeb84d9ac547308232"}, + {file = "pyarrow-20.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8ff87cc837601532cc8242d2f7e09b4e02404de1b797aee747dd4ba4bd6313f"}, + {file = "pyarrow-20.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:7a3a5dcf54286e6141d5114522cf31dd67a9e7c9133d150799f30ee302a7a1ab"}, + {file = "pyarrow-20.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a6ad3e7758ecf559900261a4df985662df54fb7fdb55e8e3b3aa99b23d526b62"}, + {file = "pyarrow-20.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6bb830757103a6cb300a04610e08d9636f0cd223d32f388418ea893a3e655f1c"}, + {file = "pyarrow-20.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:96e37f0766ecb4514a899d9a3554fadda770fb57ddf42b63d80f14bc20aa7db3"}, + {file = "pyarrow-20.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:3346babb516f4b6fd790da99b98bed9708e3f02e734c84971faccb20736848dc"}, + {file = "pyarrow-20.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:75a51a5b0eef32727a247707d4755322cb970be7e935172b6a3a9f9ae98404ba"}, + {file = "pyarrow-20.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:211d5e84cecc640c7a3ab900f930aaff5cd2702177e0d562d426fb7c4f737781"}, + {file = "pyarrow-20.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ba3cf4182828be7a896cbd232aa8dd6a31bd1f9e32776cc3796c012855e1199"}, + {file = "pyarrow-20.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c3a01f313ffe27ac4126f4c2e5ea0f36a5fc6ab51f8726cf41fee4b256680bd"}, + {file = "pyarrow-20.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:a2791f69ad72addd33510fec7bb14ee06c2a448e06b649e264c094c5b5f7ce28"}, + {file = "pyarrow-20.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:4250e28a22302ce8692d3a0e8ec9d9dde54ec00d237cff4dfa9c1fbf79e472a8"}, + {file = "pyarrow-20.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:89e030dc58fc760e4010148e6ff164d2f44441490280ef1e97a542375e41058e"}, + {file = "pyarrow-20.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6102b4864d77102dbbb72965618e204e550135a940c2534711d5ffa787df2a5a"}, + {file = "pyarrow-20.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:96d6a0a37d9c98be08f5ed6a10831d88d52cac7b13f5287f1e0f625a0de8062b"}, + {file = "pyarrow-20.0.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:a15532e77b94c61efadde86d10957950392999503b3616b2ffcef7621a002893"}, + {file = "pyarrow-20.0.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:dd43f58037443af715f34f1322c782ec463a3c8a94a85fdb2d987ceb5658e061"}, + {file = "pyarrow-20.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa0d288143a8585806e3cc7c39566407aab646fb9ece164609dac1cfff45f6ae"}, + {file = "pyarrow-20.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6953f0114f8d6f3d905d98e987d0924dabce59c3cda380bdfaa25a6201563b4"}, + {file = "pyarrow-20.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:991f85b48a8a5e839b2128590ce07611fae48a904cae6cab1f089c5955b57eb5"}, + {file = "pyarrow-20.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:97c8dc984ed09cb07d618d57d8d4b67a5100a30c3818c2fb0b04599f0da2de7b"}, + {file = "pyarrow-20.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9b71daf534f4745818f96c214dbc1e6124d7daf059167330b610fc69b6f3d3e3"}, + {file = "pyarrow-20.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e8b88758f9303fa5a83d6c90e176714b2fd3852e776fc2d7e42a22dd6c2fb368"}, + {file = "pyarrow-20.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:30b3051b7975801c1e1d387e17c588d8ab05ced9b1e14eec57915f79869b5031"}, + {file = "pyarrow-20.0.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:ca151afa4f9b7bc45bcc791eb9a89e90a9eb2772767d0b1e5389609c7d03db63"}, + {file = "pyarrow-20.0.0-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:4680f01ecd86e0dd63e39eb5cd59ef9ff24a9d166db328679e36c108dc993d4c"}, + {file = "pyarrow-20.0.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f4c8534e2ff059765647aa69b75d6543f9fef59e2cd4c6d18015192565d2b70"}, + {file = "pyarrow-20.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e1f8a47f4b4ae4c69c4d702cfbdfe4d41e18e5c7ef6f1bb1c50918c1e81c57b"}, + {file = "pyarrow-20.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:a1f60dc14658efaa927f8214734f6a01a806d7690be4b3232ba526836d216122"}, + {file = "pyarrow-20.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:204a846dca751428991346976b914d6d2a82ae5b8316a6ed99789ebf976551e6"}, + {file = "pyarrow-20.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f3b117b922af5e4c6b9a9115825726cac7d8b1421c37c2b5e24fbacc8930612c"}, + {file = "pyarrow-20.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e724a3fd23ae5b9c010e7be857f4405ed5e679db5c93e66204db1a69f733936a"}, + {file = "pyarrow-20.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:82f1ee5133bd8f49d31be1299dc07f585136679666b502540db854968576faf9"}, + {file = "pyarrow-20.0.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:1bcbe471ef3349be7714261dea28fe280db574f9d0f77eeccc195a2d161fd861"}, + {file = "pyarrow-20.0.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:a18a14baef7d7ae49247e75641fd8bcbb39f44ed49a9fc4ec2f65d5031aa3b96"}, + {file = "pyarrow-20.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb497649e505dc36542d0e68eca1a3c94ecbe9799cb67b578b55f2441a247fbc"}, + {file = "pyarrow-20.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11529a2283cb1f6271d7c23e4a8f9f8b7fd173f7360776b668e509d712a02eec"}, + {file = "pyarrow-20.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fc1499ed3b4b57ee4e090e1cea6eb3584793fe3d1b4297bbf53f09b434991a5"}, + {file = "pyarrow-20.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:db53390eaf8a4dab4dbd6d93c85c5cf002db24902dbff0ca7d988beb5c9dd15b"}, + {file = "pyarrow-20.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:851c6a8260ad387caf82d2bbf54759130534723e37083111d4ed481cb253cc0d"}, + {file = "pyarrow-20.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e22f80b97a271f0a7d9cd07394a7d348f80d3ac63ed7cc38b6d1b696ab3b2619"}, + {file = "pyarrow-20.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:9965a050048ab02409fb7cbbefeedba04d3d67f2cc899eff505cc084345959ca"}, + {file = "pyarrow-20.0.0.tar.gz", hash = "sha256:febc4a913592573c8d5805091a6c2b5064c8bd6e002131f01061797d91c783c1"}, +] + +[package.extras] +test = ["cffi", "hypothesis", "pandas", "pytest", "pytz"] + +[[package]] +name = "pyasn1" +version = "0.6.1" +description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"}, + {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"}, +] + +[[package]] +name = "pyasn1-modules" +version = "0.4.2" +description = "A collection of ASN.1-based protocols modules" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a"}, + {file = "pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6"}, +] + +[package.dependencies] +pyasn1 = ">=0.6.1,<0.7.0" + +[[package]] +name = "pydantic" +version = "2.11.7" +description = "Data validation using Python type hints" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b"}, + {file = "pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db"}, +] + +[package.dependencies] +annotated-types = ">=0.6.0" +pydantic-core = "2.33.2" +typing-extensions = ">=4.12.2" +typing-inspection = ">=0.4.0" + +[package.extras] +email = ["email-validator (>=2.0.0)"] +timezone = ["tzdata"] + +[[package]] +name = "pydantic-core" +version = "2.33.2" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8"}, + {file = "pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a"}, + {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac"}, + {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a"}, + {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b"}, + {file = "pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22"}, + {file = "pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640"}, + {file = "pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7"}, + {file = "pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e"}, + {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d"}, + {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30"}, + {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf"}, + {file = "pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51"}, + {file = "pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab"}, + {file = "pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65"}, + {file = "pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc"}, + {file = "pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b"}, + {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1"}, + {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6"}, + {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea"}, + {file = "pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290"}, + {file = "pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2"}, + {file = "pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab"}, + {file = "pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f"}, + {file = "pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56"}, + {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5"}, + {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e"}, + {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162"}, + {file = "pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849"}, + {file = "pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9"}, + {file = "pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9"}, + {file = "pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac"}, + {file = "pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5"}, + {file = "pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9"}, + {file = "pydantic_core-2.33.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a2b911a5b90e0374d03813674bf0a5fbbb7741570dcd4b4e85a2e48d17def29d"}, + {file = "pydantic_core-2.33.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6fa6dfc3e4d1f734a34710f391ae822e0a8eb8559a85c6979e14e65ee6ba2954"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54c939ee22dc8e2d545da79fc5381f1c020d6d3141d3bd747eab59164dc89fb"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53a57d2ed685940a504248187d5685e49eb5eef0f696853647bf37c418c538f7"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09fb9dd6571aacd023fe6aaca316bd01cf60ab27240d7eb39ebd66a3a15293b4"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e6116757f7959a712db11f3e9c0a99ade00a5bbedae83cb801985aa154f071b"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d55ab81c57b8ff8548c3e4947f119551253f4e3787a7bbc0b6b3ca47498a9d3"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c20c462aa4434b33a2661701b861604913f912254e441ab8d78d30485736115a"}, + {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44857c3227d3fb5e753d5fe4a3420d6376fa594b07b621e220cd93703fe21782"}, + {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:eb9b459ca4df0e5c87deb59d37377461a538852765293f9e6ee834f0435a93b9"}, + {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9fcd347d2cc5c23b06de6d3b7b8275be558a0c90549495c699e379a80bf8379e"}, + {file = "pydantic_core-2.33.2-cp39-cp39-win32.whl", hash = "sha256:83aa99b1285bc8f038941ddf598501a86f1536789740991d7d8756e34f1e74d9"}, + {file = "pydantic_core-2.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:f481959862f57f29601ccced557cc2e817bce7533ab8e01a797a48b49c9692b3"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:87acbfcf8e90ca885206e98359d7dca4bcbb35abdc0ff66672a293e1d7a19101"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f92c15cd1e97d4b12acd1cc9004fa092578acfa57b67ad5e43a197175d01a64"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f26877a748dc4251cfcfda9dfb5f13fcb034f5308388066bcfe9031b63ae7d"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac89aea9af8cd672fa7b510e7b8c33b0bba9a43186680550ccf23020f32d535"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970919794d126ba8645f3837ab6046fb4e72bbc057b3709144066204c19a455d"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3eb3fe62804e8f859c49ed20a8451342de53ed764150cb14ca71357c765dc2a6"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3abcd9392a36025e3bd55f9bd38d908bd17962cc49bc6da8e7e96285336e2bca"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3a1c81334778f9e3af2f8aeb7a960736e5cab1dfebfb26aabca09afd2906c039"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27"}, + {file = "pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + +[[package]] +name = "pyoso" +version = "0.5.1" +description = "" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyoso-0.5.1-py3-none-any.whl", hash = "sha256:1947cb4d2c4c51995e09697a02b5d63abe6918e0cd3596665b682b128fc326a7"}, + {file = "pyoso-0.5.1.tar.gz", hash = "sha256:3086898e61cf68af0f0eeabfd8a5931665e0ec3162e059caaa546f209b239411"}, +] + +[package.dependencies] +pandas = ">=1.2.0" +requests = ">=2.32.4" +sqlglot = ">=26.16.4" + +[package.extras] +semantic = ["oso-semantic"] + +[[package]] +name = "pyparsing" +version = "3.2.3" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf"}, + {file = "pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-dotenv" +version = "1.1.1" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.9" +files = [ + {file = "python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc"}, + {file = "python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + +[[package]] +name = "pytz" +version = "2025.2" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00"}, + {file = "pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3"}, +] + +[[package]] +name = "requests" +version = "2.32.4" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c"}, + {file = "requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset_normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "rsa" +version = "4.9.1" +description = "Pure-Python RSA implementation" +optional = false +python-versions = "<4,>=3.6" +files = [ + {file = "rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762"}, + {file = "rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75"}, +] + +[package.dependencies] +pyasn1 = ">=0.1.3" + +[[package]] +name = "six" +version = "1.17.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "sqlglot" +version = "26.31.0" +description = "An easily customizable SQL parser and transpiler" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sqlglot-26.31.0-py3-none-any.whl", hash = "sha256:1f0e1071b53faebdfcbfa019a831ce0c2b71e4d825f0f08306c5f20c1aef0898"}, + {file = "sqlglot-26.31.0.tar.gz", hash = "sha256:e9b8f52d02e21636cd7e463af29db0b86707437b9d468b7b2166b67fa96cdd87"}, +] + +[package.extras] +dev = ["duckdb (>=0.6)", "maturin (>=1.4,<2.0)", "mypy", "pandas", "pandas-stubs", "pdoc", "pre-commit", "pyperf", "python-dateutil", "pytz", "ruff (==0.7.2)", "types-python-dateutil", "types-pytz", "typing_extensions"] +rs = ["sqlglotrs (==0.6.1)"] + +[[package]] +name = "tqdm" +version = "4.67.1" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + +[[package]] +name = "typing-extensions" +version = "4.14.0" +description = "Backported and Experimental Type Hints for Python 3.9+" +optional = false +python-versions = ">=3.9" +files = [ + {file = "typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af"}, + {file = "typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4"}, +] + +[[package]] +name = "typing-inspection" +version = "0.4.1" +description = "Runtime typing introspection tools" +optional = false +python-versions = ">=3.9" +files = [ + {file = "typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51"}, + {file = "typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28"}, +] + +[package.dependencies] +typing-extensions = ">=4.12.0" + +[[package]] +name = "tzdata" +version = "2025.2" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}, + {file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}, +] + +[[package]] +name = "uritemplate" +version = "4.2.0" +description = "Implementation of RFC 6570 URI Templates" +optional = false +python-versions = ">=3.9" +files = [ + {file = "uritemplate-4.2.0-py3-none-any.whl", hash = "sha256:962201ba1c4edcab02e60f9a0d3821e82dfc5d2d6662a21abd533879bdb8a686"}, + {file = "uritemplate-4.2.0.tar.gz", hash = "sha256:480c2ed180878955863323eea31b0ede668795de182617fef9c6ca09e6ec9d0e"}, +] + +[[package]] +name = "urllib3" +version = "2.5.0" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.9" +files = [ + {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, + {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.11" +content-hash = "2698c4c83407acc7ab52e9bcc798061a0c2d3dbc5e8ab28ec4d4c1ead2c6e1d2" diff --git a/experiments/ethereum-repo-clusters/pyproject.toml b/experiments/ethereum-repo-clusters/pyproject.toml new file mode 100644 index 00000000..c1b65ece --- /dev/null +++ b/experiments/ethereum-repo-clusters/pyproject.toml @@ -0,0 +1,23 @@ +[tool.poetry] +name = "ethereum-repo-clusters" +version = "0.1.0" +description = "" +authors = ["Your Name "] +readme = "README.md" +package-mode = false + +[tool.poetry.dependencies] +python = "^3.11" +pandas = "^2.3.0" +requests = "^2.32.4" +pyoso = "^0.5.1" +google-generativeai = "^0.8.5" +pydantic = "^2.11.7" +python-dotenv = "^1.1.1" +click = "^8.2.1" +pyarrow = "^20.0.0" + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/experiments/ethereum-repo-clusters/requirements.txt b/experiments/ethereum-repo-clusters/requirements.txt deleted file mode 100644 index 7ab7b91e..00000000 --- a/experiments/ethereum-repo-clusters/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -pandas>=2.0.0 -requests>=2.31.0 -pyoso>=0.1.0 -google-generativeai>=0.3.0 -pydantic>=2.0.0 -python-dotenv>=1.0.0 -click>=8.0.0 -pyarrow>=14.0.0 # For parquet support diff --git a/experiments/ethereum-repo-clusters/results/ethereum_repo_categories_v1.parquet b/experiments/ethereum-repo-clusters/results/ethereum_repo_categories_v1.parquet new file mode 100644 index 00000000..4a76475b Binary files /dev/null and b/experiments/ethereum-repo-clusters/results/ethereum_repo_categories_v1.parquet differ diff --git a/experiments/ethereum-repo-clusters/results/ethereum_repo_categories_v2.parquet b/experiments/ethereum-repo-clusters/results/ethereum_repo_categories_v2.parquet new file mode 100644 index 00000000..a4c246e4 Binary files /dev/null and b/experiments/ethereum-repo-clusters/results/ethereum_repo_categories_v2.parquet differ diff --git a/experiments/ethereum-repo-clusters/setup.py b/experiments/ethereum-repo-clusters/setup.py deleted file mode 100644 index 1b43d1c3..00000000 --- a/experiments/ethereum-repo-clusters/setup.py +++ /dev/null @@ -1,16 +0,0 @@ -from setuptools import setup, find_packages - -setup( - name="devtooling_labels", - version="0.1.0", - packages=find_packages(), - install_requires=[ - "pandas>=2.0.0", - "requests>=2.31.0", - "pyoso>=0.1.0", - "google-generativeai>=0.3.0", - "pydantic>=2.0.0", - "python-dotenv>=1.0.0", - ], - python_requires=">=3.8", -) \ No newline at end of file diff --git a/tutorials/FundingMetrics.ipynb b/tutorials/FundingMetrics.ipynb index d64c4876..83d0cf4a 100644 --- a/tutorials/FundingMetrics.ipynb +++ b/tutorials/FundingMetrics.ipynb @@ -81,150 +81,225 @@ " \n", " \n", " 0\n", - " GITCOIN_DONATIONS_funding_awarded_biannually\n", + " ARBITRUMFOUNDATION_funding_awarded_over_all_time\n", " \n", " \n", " 1\n", - " GITCOIN_DONATIONS_funding_awarded_daily\n", + " CLRFUND_funding_awarded_over_all_time\n", " \n", " \n", " 2\n", - " GITCOIN_DONATIONS_funding_awarded_monthly\n", + " DAODROPS_funding_awarded_over_all_time\n", " \n", " \n", " 3\n", - " GITCOIN_DONATIONS_funding_awarded_over_all_time\n", + " GITCOIN_DONATIONS_funding_awarded_biannually\n", " \n", " \n", " 4\n", - " GITCOIN_DONATIONS_funding_awarded_quarterly\n", + " GITCOIN_DONATIONS_funding_awarded_daily\n", " \n", " \n", " 5\n", - " GITCOIN_DONATIONS_funding_awarded_weekly\n", + " GITCOIN_DONATIONS_funding_awarded_monthly\n", " \n", " \n", " 6\n", - " GITCOIN_DONATIONS_funding_awarded_yearly\n", + " GITCOIN_DONATIONS_funding_awarded_over_all_time\n", " \n", " \n", " 7\n", - " GITCOIN_MATCHING_funding_awarded_biannually\n", + " GITCOIN_DONATIONS_funding_awarded_quarterly\n", " \n", " \n", " 8\n", - " GITCOIN_MATCHING_funding_awarded_daily\n", + " GITCOIN_DONATIONS_funding_awarded_weekly\n", " \n", " \n", " 9\n", - " GITCOIN_MATCHING_funding_awarded_monthly\n", + " GITCOIN_DONATIONS_funding_awarded_yearly\n", " \n", " \n", " 10\n", - " GITCOIN_MATCHING_funding_awarded_over_all_time\n", + " GITCOIN_MATCHING_funding_awarded_biannually\n", " \n", " \n", " 11\n", - " GITCOIN_MATCHING_funding_awarded_quarterly\n", + " GITCOIN_MATCHING_funding_awarded_daily\n", " \n", " \n", " 12\n", - " GITCOIN_MATCHING_funding_awarded_weekly\n", + " GITCOIN_MATCHING_funding_awarded_monthly\n", " \n", " \n", " 13\n", - " GITCOIN_MATCHING_funding_awarded_yearly\n", + " GITCOIN_MATCHING_funding_awarded_over_all_time\n", " \n", " \n", " 14\n", - " OPEN_COLLECTIVE_funding_received_biannually\n", + " GITCOIN_MATCHING_funding_awarded_quarterly\n", " \n", " \n", " 15\n", - " OPEN_COLLECTIVE_funding_received_daily\n", + " GITCOIN_MATCHING_funding_awarded_weekly\n", " \n", " \n", " 16\n", - " OPEN_COLLECTIVE_funding_received_monthly\n", + " GITCOIN_MATCHING_funding_awarded_yearly\n", " \n", " \n", " 17\n", - " OPEN_COLLECTIVE_funding_received_over_all_time\n", + " OCTANT_funding_awarded_biannually\n", " \n", " \n", " 18\n", - " OPEN_COLLECTIVE_funding_received_quarterly\n", + " OCTANT_funding_awarded_over_all_time\n", " \n", " \n", " 19\n", - " OPEN_COLLECTIVE_funding_received_weekly\n", + " OPEN_COLLECTIVE_funding_received_biannually\n", " \n", " \n", " 20\n", - " OPEN_COLLECTIVE_funding_received_yearly\n", + " OPEN_COLLECTIVE_funding_received_daily\n", " \n", " \n", " 21\n", - " OSS_FUNDING_funding_awarded_biannually\n", + " OPEN_COLLECTIVE_funding_received_monthly\n", " \n", " \n", " 22\n", - " OSS_FUNDING_funding_awarded_daily\n", + " OPEN_COLLECTIVE_funding_received_over_all_time\n", " \n", " \n", " 23\n", - " OSS_FUNDING_funding_awarded_monthly\n", + " OPEN_COLLECTIVE_funding_received_quarterly\n", " \n", " \n", " 24\n", - " OSS_FUNDING_funding_awarded_over_all_time\n", + " OPEN_COLLECTIVE_funding_received_weekly\n", " \n", " \n", " 25\n", - " OSS_FUNDING_funding_awarded_quarterly\n", + " OPEN_COLLECTIVE_funding_received_yearly\n", " \n", " \n", " 26\n", - " OSS_FUNDING_funding_awarded_weekly\n", + " OPTIMISM_GOVGRANTS_funding_awarded_biannually\n", " \n", " \n", " 27\n", + " OPTIMISM_GOVGRANTS_funding_awarded_over_all_time\n", + " \n", + " \n", + " 28\n", + " OPTIMISM_GOVGRANTS_funding_awarded_quarterly\n", + " \n", + " \n", + " 29\n", + " OPTIMISM_RETROFUNDING_funding_awarded_biannually\n", + " \n", + " \n", + " 30\n", + " OPTIMISM_RETROFUNDING_funding_awarded_daily\n", + " \n", + " \n", + " 31\n", + " OPTIMISM_RETROFUNDING_funding_awarded_monthly\n", + " \n", + " \n", + " 32\n", + " OPTIMISM_RETROFUNDING_funding_awarded_over_all...\n", + " \n", + " \n", + " 33\n", + " OPTIMISM_RETROFUNDING_funding_awarded_quarterly\n", + " \n", + " \n", + " 34\n", + " OPTIMISM_RETROFUNDING_funding_awarded_weekly\n", + " \n", + " \n", + " 35\n", + " OSS_FUNDING_funding_awarded_biannually\n", + " \n", + " \n", + " 36\n", + " OSS_FUNDING_funding_awarded_daily\n", + " \n", + " \n", + " 37\n", + " OSS_FUNDING_funding_awarded_monthly\n", + " \n", + " \n", + " 38\n", + " OSS_FUNDING_funding_awarded_quarterly\n", + " \n", + " \n", + " 39\n", + " OSS_FUNDING_funding_awarded_weekly\n", + " \n", + " \n", + " 40\n", " OSS_FUNDING_funding_awarded_yearly\n", " \n", + " \n", + " 41\n", + " STELLAR_funding_awarded_biannually\n", + " \n", + " \n", + " 42\n", + " STELLAR_funding_awarded_over_all_time\n", + " \n", " \n", "\n", "" ], "text/plain": [ - " metric_name\n", - "0 GITCOIN_DONATIONS_funding_awarded_biannually\n", - "1 GITCOIN_DONATIONS_funding_awarded_daily\n", - "2 GITCOIN_DONATIONS_funding_awarded_monthly\n", - "3 GITCOIN_DONATIONS_funding_awarded_over_all_time\n", - "4 GITCOIN_DONATIONS_funding_awarded_quarterly\n", - "5 GITCOIN_DONATIONS_funding_awarded_weekly\n", - "6 GITCOIN_DONATIONS_funding_awarded_yearly\n", - "7 GITCOIN_MATCHING_funding_awarded_biannually\n", - "8 GITCOIN_MATCHING_funding_awarded_daily\n", - "9 GITCOIN_MATCHING_funding_awarded_monthly\n", - "10 GITCOIN_MATCHING_funding_awarded_over_all_time\n", - "11 GITCOIN_MATCHING_funding_awarded_quarterly\n", - "12 GITCOIN_MATCHING_funding_awarded_weekly\n", - "13 GITCOIN_MATCHING_funding_awarded_yearly\n", - "14 OPEN_COLLECTIVE_funding_received_biannually\n", - "15 OPEN_COLLECTIVE_funding_received_daily\n", - "16 OPEN_COLLECTIVE_funding_received_monthly\n", - "17 OPEN_COLLECTIVE_funding_received_over_all_time\n", - "18 OPEN_COLLECTIVE_funding_received_quarterly\n", - "19 OPEN_COLLECTIVE_funding_received_weekly\n", - "20 OPEN_COLLECTIVE_funding_received_yearly\n", - "21 OSS_FUNDING_funding_awarded_biannually\n", - "22 OSS_FUNDING_funding_awarded_daily\n", - "23 OSS_FUNDING_funding_awarded_monthly\n", - "24 OSS_FUNDING_funding_awarded_over_all_time\n", - "25 OSS_FUNDING_funding_awarded_quarterly\n", - "26 OSS_FUNDING_funding_awarded_weekly\n", - "27 OSS_FUNDING_funding_awarded_yearly" + " metric_name\n", + "0 ARBITRUMFOUNDATION_funding_awarded_over_all_time\n", + "1 CLRFUND_funding_awarded_over_all_time\n", + "2 DAODROPS_funding_awarded_over_all_time\n", + "3 GITCOIN_DONATIONS_funding_awarded_biannually\n", + "4 GITCOIN_DONATIONS_funding_awarded_daily\n", + "5 GITCOIN_DONATIONS_funding_awarded_monthly\n", + "6 GITCOIN_DONATIONS_funding_awarded_over_all_time\n", + "7 GITCOIN_DONATIONS_funding_awarded_quarterly\n", + "8 GITCOIN_DONATIONS_funding_awarded_weekly\n", + "9 GITCOIN_DONATIONS_funding_awarded_yearly\n", + "10 GITCOIN_MATCHING_funding_awarded_biannually\n", + "11 GITCOIN_MATCHING_funding_awarded_daily\n", + "12 GITCOIN_MATCHING_funding_awarded_monthly\n", + "13 GITCOIN_MATCHING_funding_awarded_over_all_time\n", + "14 GITCOIN_MATCHING_funding_awarded_quarterly\n", + "15 GITCOIN_MATCHING_funding_awarded_weekly\n", + "16 GITCOIN_MATCHING_funding_awarded_yearly\n", + "17 OCTANT_funding_awarded_biannually\n", + "18 OCTANT_funding_awarded_over_all_time\n", + "19 OPEN_COLLECTIVE_funding_received_biannually\n", + "20 OPEN_COLLECTIVE_funding_received_daily\n", + "21 OPEN_COLLECTIVE_funding_received_monthly\n", + "22 OPEN_COLLECTIVE_funding_received_over_all_time\n", + "23 OPEN_COLLECTIVE_funding_received_quarterly\n", + "24 OPEN_COLLECTIVE_funding_received_weekly\n", + "25 OPEN_COLLECTIVE_funding_received_yearly\n", + "26 OPTIMISM_GOVGRANTS_funding_awarded_biannually\n", + "27 OPTIMISM_GOVGRANTS_funding_awarded_over_all_time\n", + "28 OPTIMISM_GOVGRANTS_funding_awarded_quarterly\n", + "29 OPTIMISM_RETROFUNDING_funding_awarded_biannually\n", + "30 OPTIMISM_RETROFUNDING_funding_awarded_daily\n", + "31 OPTIMISM_RETROFUNDING_funding_awarded_monthly\n", + "32 OPTIMISM_RETROFUNDING_funding_awarded_over_all...\n", + "33 OPTIMISM_RETROFUNDING_funding_awarded_quarterly\n", + "34 OPTIMISM_RETROFUNDING_funding_awarded_weekly\n", + "35 OSS_FUNDING_funding_awarded_biannually\n", + "36 OSS_FUNDING_funding_awarded_daily\n", + "37 OSS_FUNDING_funding_awarded_monthly\n", + "38 OSS_FUNDING_funding_awarded_quarterly\n", + "39 OSS_FUNDING_funding_awarded_weekly\n", + "40 OSS_FUNDING_funding_awarded_yearly\n", + "41 STELLAR_funding_awarded_biannually\n", + "42 STELLAR_funding_awarded_over_all_time" ] }, "execution_count": 3, @@ -287,28 +362,64 @@ " \n", " \n", " 0\n", - " OSS_FUNDING_funding_awarded_over_all_time\n", - " 364887873.600968\n", + " OPTIMISM_RETROFUNDING_funding_awarded_over_all...\n", + " 138245667.349578\n", " \n", " \n", " 1\n", - " GITCOIN_MATCHING_funding_awarded_over_all_time\n", - " 13305117.158144\n", + " ARBITRUMFOUNDATION_funding_awarded_over_all_time\n", + " 121538452.0\n", " \n", " \n", " 2\n", + " OPTIMISM_GOVGRANTS_funding_awarded_over_all_time\n", + " 101425950.39\n", + " \n", + " \n", + " 3\n", + " STELLAR_funding_awarded_over_all_time\n", + " 33517284.98\n", + " \n", + " \n", + " 4\n", + " GITCOIN_MATCHING_funding_awarded_over_all_time\n", + " 12743948.169964\n", + " \n", + " \n", + " 5\n", " GITCOIN_DONATIONS_funding_awarded_over_all_time\n", - " 11666103.711711\n", + " 10897861.066639\n", + " \n", + " \n", + " 6\n", + " OCTANT_funding_awarded_over_all_time\n", + " 3871958.50952\n", + " \n", + " \n", + " 7\n", + " DAODROPS_funding_awarded_over_all_time\n", + " 168634.0\n", + " \n", + " \n", + " 8\n", + " CLRFUND_funding_awarded_over_all_time\n", + " 55286.24013\n", " \n", " \n", "\n", "" ], "text/plain": [ - " metric_name total_amount_in_usd\n", - "0 OSS_FUNDING_funding_awarded_over_all_time 364887873.600968\n", - "1 GITCOIN_MATCHING_funding_awarded_over_all_time 13305117.158144\n", - "2 GITCOIN_DONATIONS_funding_awarded_over_all_time 11666103.711711" + " metric_name total_amount_in_usd\n", + "0 OPTIMISM_RETROFUNDING_funding_awarded_over_all... 138245667.349578\n", + "1 ARBITRUMFOUNDATION_funding_awarded_over_all_time 121538452.0\n", + "2 OPTIMISM_GOVGRANTS_funding_awarded_over_all_time 101425950.39\n", + "3 STELLAR_funding_awarded_over_all_time 33517284.98\n", + "4 GITCOIN_MATCHING_funding_awarded_over_all_time 12743948.169964\n", + "5 GITCOIN_DONATIONS_funding_awarded_over_all_time 10897861.066639\n", + "6 OCTANT_funding_awarded_over_all_time 3871958.50952\n", + "7 DAODROPS_funding_awarded_over_all_time 168634.0\n", + "8 CLRFUND_funding_awarded_over_all_time 55286.24013" ] }, "execution_count": 4, @@ -383,43 +494,43 @@ " \n", " \n", " 2\n", - " Synthetix\n", - " 10022628.074157\n", + " Velodrome\n", + " 10836736.04374\n", " \n", " \n", " 3\n", - " Perpetual Protocol\n", - " 9287212.140718\n", + " Gains Network\n", + " 7909635.9075\n", " \n", " \n", " 4\n", - " Gains Network\n", - " 7898396.135\n", + " Synthetix\n", + " 7247628.074157\n", " \n", " \n", " 5\n", - " Velodrome\n", - " 7895037.76024\n", + " Camelot\n", + " 5407500.0\n", " \n", " \n", " 6\n", - " Camelot\n", - " 5407500.0\n", + " Vertex Protocol\n", + " 5250000.0\n", " \n", " \n", " 7\n", - " Stargate Finance\n", - " 5289458.865658\n", + " Radiant\n", + " 4991077.0\n", " \n", " \n", " 8\n", - " Vertex Protocol\n", - " 5250000.0\n", + " Stargate Finance\n", + " 4879172.708658\n", " \n", " \n", " 9\n", - " Radiant\n", - " 4991077.0\n", + " Perpetual Protocol\n", + " 4787212.140718\n", " \n", " \n", "\n", @@ -429,14 +540,14 @@ " project_display_name total_amount_in_usd\n", "0 GMX 21000000.0\n", "1 MUX Protocol 10876479.0\n", - "2 Synthetix 10022628.074157\n", - "3 Perpetual Protocol 9287212.140718\n", - "4 Gains Network 7898396.135\n", - "5 Velodrome 7895037.76024\n", - "6 Camelot 5407500.0\n", - "7 Stargate Finance 5289458.865658\n", - "8 Vertex Protocol 5250000.0\n", - "9 Radiant 4991077.0" + "2 Velodrome 10836736.04374\n", + "3 Gains Network 7909635.9075\n", + "4 Synthetix 7247628.074157\n", + "5 Camelot 5407500.0\n", + "6 Vertex Protocol 5250000.0\n", + "7 Radiant 4991077.0\n", + "8 Stargate Finance 4879172.708658\n", + "9 Perpetual Protocol 4787212.140718" ] }, "execution_count": 5, @@ -502,12 +613,12 @@ " \n", " 0\n", " Gitcoin\n", - " 1099895.038376\n", + " 1040187.136146\n", " \n", " \n", " 1\n", " Revoke\n", - " 748859.365745\n", + " 748071.985745\n", " \n", " \n", " 2\n", @@ -536,35 +647,35 @@ " \n", " \n", " 7\n", - " ethers.js\n", - " 190702.539836\n", + " rotki\n", + " 159744.88374\n", " \n", " \n", " 8\n", - " rotki\n", - " 174990.340416\n", + " ethers.js\n", + " 149548.961252\n", " \n", " \n", " 9\n", - " Taho\n", - " 170854.869607\n", + " Lighthouse by Sigma Prime\n", + " 132816.547253\n", " \n", " \n", "\n", "" ], "text/plain": [ - " project_display_name total_amount_in_usd\n", - "0 Gitcoin 1099895.038376\n", - "1 Revoke 748859.365745\n", - "2 DefiLlama 429924.507285\n", - "3 Hey 360529.24178\n", - "4 JediSwap 333277.670918\n", - "5 Dark Forest 332205.420888\n", - "6 ZigZag Exchange 210175.931949\n", - "7 ethers.js 190702.539836\n", - "8 rotki 174990.340416\n", - "9 Taho 170854.869607" + " project_display_name total_amount_in_usd\n", + "0 Gitcoin 1040187.136146\n", + "1 Revoke 748071.985745\n", + "2 DefiLlama 429924.507285\n", + "3 Hey 360529.24178\n", + "4 JediSwap 333277.670918\n", + "5 Dark Forest 332205.420888\n", + "6 ZigZag Exchange 210175.931949\n", + "7 rotki 159744.88374\n", + "8 ethers.js 149548.961252\n", + "9 Lighthouse by Sigma Prime 132816.547253" ] }, "execution_count": 6, @@ -716,6 +827,699 @@ "\"\"\")" ] }, + { + "cell_type": "markdown", + "id": "105787d9-2cd7-49f5-883e-80fc7c904794", + "metadata": {}, + "source": [ + "### To/from funders (summary metrics)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "276f4c69-c824-4acc-b77f-8009e7719100", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
project_iddisplay_namefunding_sourcetotal_amount_in_usd
0dNDkpiWWFxWM+fz0JbPapZpz/TlsoYQCJevD3ICcAHU=BOBOPTIMISM_GOVGRANTS997500.0
18ranj8ZjbHqnVkAyhSNS9HAKO0VN/Tb34jZdBROI788=Mint BlockchainOPTIMISM_GOVGRANTS997500.0
2qnQ1PFj4fkRd6WPxzt5EHNykmTn5G/nYVvWkWjs0h0g=RevmOPTIMISM_RETROFUNDING982507.285439
3ZtwRwweUfJxkM3rtVoIfvvOaqHRc7CGlSCAKE8VgmN0=Aerodrome FinanceOPTIMISM_RETROFUNDING958989.311521
4lPxNsS/BATP5VXf5oTGLri62s8Um5J+Rm9nMBX+wFV4=LatticeOPTIMISM_RETROFUNDING958503.015
...............
22569FCd3zp3AhnThPkf6mxSbon88Co2iHmkcIfQAzdWbzc=DasyGITCOIN_MATCHING1010.41355
2257R1dwI8DtnoQytJHlZmQ2puJgGCi+M0Fs0/7nr58a5/o=DexKitGITCOIN_DONATIONS1007.749109
2258Q8F6p4cN/9k6DpGmVYCcjZ67J1kV3bcJmPvDI5wwz2o=dippixyzGITCOIN_MATCHING1001.623472
2259uQO9q9SKY+pM9SqxIQXR83uXfbOy9jh9K77n91nU6QA=RingsNetworkGITCOIN_MATCHING1000.425276
2260GG7aTBIpNDjKMwi8e7O/vZfc+ai8cg9Xw5+CcnR1Ks0=Soroban Pre-Order ContractSTELLAR1000.0
\n", + "

2261 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " project_id \\\n", + "0 dNDkpiWWFxWM+fz0JbPapZpz/TlsoYQCJevD3ICcAHU= \n", + "1 8ranj8ZjbHqnVkAyhSNS9HAKO0VN/Tb34jZdBROI788= \n", + "2 qnQ1PFj4fkRd6WPxzt5EHNykmTn5G/nYVvWkWjs0h0g= \n", + "3 ZtwRwweUfJxkM3rtVoIfvvOaqHRc7CGlSCAKE8VgmN0= \n", + "4 lPxNsS/BATP5VXf5oTGLri62s8Um5J+Rm9nMBX+wFV4= \n", + "... ... \n", + "2256 9FCd3zp3AhnThPkf6mxSbon88Co2iHmkcIfQAzdWbzc= \n", + "2257 R1dwI8DtnoQytJHlZmQ2puJgGCi+M0Fs0/7nr58a5/o= \n", + "2258 Q8F6p4cN/9k6DpGmVYCcjZ67J1kV3bcJmPvDI5wwz2o= \n", + "2259 uQO9q9SKY+pM9SqxIQXR83uXfbOy9jh9K77n91nU6QA= \n", + "2260 GG7aTBIpNDjKMwi8e7O/vZfc+ai8cg9Xw5+CcnR1Ks0= \n", + "\n", + " display_name funding_source total_amount_in_usd \n", + "0 BOB OPTIMISM_GOVGRANTS 997500.0 \n", + "1 Mint Blockchain OPTIMISM_GOVGRANTS 997500.0 \n", + "2 Revm OPTIMISM_RETROFUNDING 982507.285439 \n", + "3 Aerodrome Finance OPTIMISM_RETROFUNDING 958989.311521 \n", + "4 Lattice OPTIMISM_RETROFUNDING 958503.015 \n", + "... ... ... ... \n", + "2256 Dasy GITCOIN_MATCHING 1010.41355 \n", + "2257 DexKit GITCOIN_DONATIONS 1007.749109 \n", + "2258 dippixyz GITCOIN_MATCHING 1001.623472 \n", + "2259 RingsNetwork GITCOIN_MATCHING 1000.425276 \n", + "2260 Soroban Pre-Order Contract STELLAR 1000.0 \n", + "\n", + "[2261 rows x 4 columns]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = client.to_pandas(\"\"\"\n", + "SELECT\n", + " p.project_id,\n", + " p.display_name,\n", + " REPLACE(m.metric_name, '_funding_awarded_over_all_time', '') AS funding_source,\n", + " SUM(km.amount) AS total_amount_in_usd\n", + "FROM key_metrics_by_project_v0 AS km\n", + "JOIN metrics_v0 AS m ON km.metric_id = m.metric_id\n", + "JOIN projects_v1 AS p ON km.project_id = p.project_id\n", + "WHERE\n", + " m.metric_name LIKE '%_funding_awarded_over_all_time'\n", + " AND (km.amount >= 1000 AND km.amount < 1000000)\n", + "GROUP BY 1,2,3\n", + "ORDER BY 4 DESC\n", + "\"\"\")\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "e326c245-5f20-4847-935b-9a05485f84a1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
from_funderdisplay_nametotal_amount_in_usd
26Optimism (Retro Funding)rotki773567.405
27Optimism (Retro Funding)Giveth763501.505973
60Optimism (Retro Funding)growthepie591839.955
107Optimism (Retro Funding)The Metagovernance Project445164.86
112Gitcoin (Matching)rotki437212.315468
165Arbitrum STIPTally350000.0
178Optimism (Retro Funding)Tally347827.48
187Optimism (Retro Funding)Hypercerts330436.12
233Optimism (Retro Funding)Praise277324.575
237Optimism (Gov Grants)Tally272000.0
239Optimism (Gov Grants)growthepie271250.0
253Octantrotki264978.05933
261Optimism (Retro Funding)BrightID260870.61
271OctantHypercerts254595.53848
316Optimism (Gov Grants)The Metagovernance Project218750.0
347Optimism (Gov Grants)Praise196000.0
416Gitcoin (Matching)BrightID167265.359323
428Octantgrowthepie160926.51583
431Gitcoin (Donations)rotki159744.88374
440Optimism (Gov Grants)rotki155385.0
470Optimism (Gov Grants)Glo Dollar150000.0
600Optimism (Gov Grants)Giveth114000.0
607Gitcoin (Donations)BrightID111565.008962
661OctantPraise97426.29811
676OctantGiveth93294.031
681Gitcoin (Matching)Giveth90637.654801
686Optimism (Gov Grants)Hypercerts90000.0
750Gitcoin (Matching)The Metagovernance Project75029.406501
802Optimism (Gov Grants)MetaGame67900.0
866Gitcoin (Matching)growthepie52982.044628
868Gitcoin (Donations)Giveth52791.595378
915Stellar Community FundGiveth50000.0
1025OctantMetaGame41578.274
1045Gitcoin (Donations)Hypercerts39848.534911
1127Gitcoin (Matching)Glo Dollar33483.098457
1158Gitcoin (Matching)Hypercerts30929.104256
1162Gitcoin (Donations)The Metagovernance Project30596.102733
1240OctantGlo Dollar24511.97
1320DAO DropsGiveth18186.0
1439OctantBrightID13053.2
1442Stellar Community FundGlo Dollar13000.0
1499DAO DropsMetaGame11287.0
1507DAO Dropsrotki10863.0
1511Gitcoin (Donations)MetaGame10676.413439
1519DAO DropsThe Metagovernance Project10439.0
1660Gitcoin (Matching)MetaGame7134.340396
1697Gitcoin (Matching)Tally6410.531839
1703Gitcoin (Donations)Glo Dollar6292.656128
1705OctantThe Metagovernance Project6251.63472
1733Gitcoin (Donations)growthepie5564.218084
1753DAO DropsPraise5326.0
1817clr.fundBrightID4256.110485
1938Gitcoin (Donations)Praise2839.37634
2058Gitcoin (Matching)Praise1902.041358
2154Gitcoin (Donations)Tally1469.24948
2163clr.fundrotki1416.561436
\n", + "
" + ], + "text/plain": [ + " from_funder display_name \\\n", + "26 Optimism (Retro Funding) rotki \n", + "27 Optimism (Retro Funding) Giveth \n", + "60 Optimism (Retro Funding) growthepie \n", + "107 Optimism (Retro Funding) The Metagovernance Project \n", + "112 Gitcoin (Matching) rotki \n", + "165 Arbitrum STIP Tally \n", + "178 Optimism (Retro Funding) Tally \n", + "187 Optimism (Retro Funding) Hypercerts \n", + "233 Optimism (Retro Funding) Praise \n", + "237 Optimism (Gov Grants) Tally \n", + "239 Optimism (Gov Grants) growthepie \n", + "253 Octant rotki \n", + "261 Optimism (Retro Funding) BrightID \n", + "271 Octant Hypercerts \n", + "316 Optimism (Gov Grants) The Metagovernance Project \n", + "347 Optimism (Gov Grants) Praise \n", + "416 Gitcoin (Matching) BrightID \n", + "428 Octant growthepie \n", + "431 Gitcoin (Donations) rotki \n", + "440 Optimism (Gov Grants) rotki \n", + "470 Optimism (Gov Grants) Glo Dollar \n", + "600 Optimism (Gov Grants) Giveth \n", + "607 Gitcoin (Donations) BrightID \n", + "661 Octant Praise \n", + "676 Octant Giveth \n", + "681 Gitcoin (Matching) Giveth \n", + "686 Optimism (Gov Grants) Hypercerts \n", + "750 Gitcoin (Matching) The Metagovernance Project \n", + "802 Optimism (Gov Grants) MetaGame \n", + "866 Gitcoin (Matching) growthepie \n", + "868 Gitcoin (Donations) Giveth \n", + "915 Stellar Community Fund Giveth \n", + "1025 Octant MetaGame \n", + "1045 Gitcoin (Donations) Hypercerts \n", + "1127 Gitcoin (Matching) Glo Dollar \n", + "1158 Gitcoin (Matching) Hypercerts \n", + "1162 Gitcoin (Donations) The Metagovernance Project \n", + "1240 Octant Glo Dollar \n", + "1320 DAO Drops Giveth \n", + "1439 Octant BrightID \n", + "1442 Stellar Community Fund Glo Dollar \n", + "1499 DAO Drops MetaGame \n", + "1507 DAO Drops rotki \n", + "1511 Gitcoin (Donations) MetaGame \n", + "1519 DAO Drops The Metagovernance Project \n", + "1660 Gitcoin (Matching) MetaGame \n", + "1697 Gitcoin (Matching) Tally \n", + "1703 Gitcoin (Donations) Glo Dollar \n", + "1705 Octant The Metagovernance Project \n", + "1733 Gitcoin (Donations) growthepie \n", + "1753 DAO Drops Praise \n", + "1817 clr.fund BrightID \n", + "1938 Gitcoin (Donations) Praise \n", + "2058 Gitcoin (Matching) Praise \n", + "2154 Gitcoin (Donations) Tally \n", + "2163 clr.fund rotki \n", + "\n", + " total_amount_in_usd \n", + "26 773567.405 \n", + "27 763501.505973 \n", + "60 591839.955 \n", + "107 445164.86 \n", + "112 437212.315468 \n", + "165 350000.0 \n", + "178 347827.48 \n", + "187 330436.12 \n", + "233 277324.575 \n", + "237 272000.0 \n", + "239 271250.0 \n", + "253 264978.05933 \n", + "261 260870.61 \n", + "271 254595.53848 \n", + "316 218750.0 \n", + "347 196000.0 \n", + "416 167265.359323 \n", + "428 160926.51583 \n", + "431 159744.88374 \n", + "440 155385.0 \n", + "470 150000.0 \n", + "600 114000.0 \n", + "607 111565.008962 \n", + "661 97426.29811 \n", + "676 93294.031 \n", + "681 90637.654801 \n", + "686 90000.0 \n", + "750 75029.406501 \n", + "802 67900.0 \n", + "866 52982.044628 \n", + "868 52791.595378 \n", + "915 50000.0 \n", + "1025 41578.274 \n", + "1045 39848.534911 \n", + "1127 33483.098457 \n", + "1158 30929.104256 \n", + "1162 30596.102733 \n", + "1240 24511.97 \n", + "1320 18186.0 \n", + "1439 13053.2 \n", + "1442 13000.0 \n", + "1499 11287.0 \n", + "1507 10863.0 \n", + "1511 10676.413439 \n", + "1519 10439.0 \n", + "1660 7134.340396 \n", + "1697 6410.531839 \n", + "1703 6292.656128 \n", + "1705 6251.63472 \n", + "1733 5564.218084 \n", + "1753 5326.0 \n", + "1817 4256.110485 \n", + "1938 2839.37634 \n", + "2058 1902.041358 \n", + "2154 1469.24948 \n", + "2163 1416.561436 " + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "popular_projects = list(df.groupby('display_name')['funding_source'].nunique().sort_values(ascending=False).index[:10])\n", + "dff = df[df['display_name'].isin(popular_projects)].copy()\n", + "funder_names = {\n", + " 'OPTIMISM_RETROFUNDING': 'Optimism (Retro Funding)',\n", + " 'GITCOIN_MATCHING': 'Gitcoin (Matching)',\n", + " 'ARBITRUMFOUNDATION': 'Arbitrum STIP',\n", + " 'OPTIMISM_GOVGRANTS': 'Optimism (Gov Grants)',\n", + " 'OCTANT': 'Octant', \n", + " 'GITCOIN_DONATIONS': 'Gitcoin (Donations)', \n", + " 'STELLAR': 'Stellar Community Fund', \n", + " 'DAODROPS': 'DAO Drops', \n", + " 'CLRFUND': 'clr.fund'\n", + "}\n", + "dff['from_funder'] = dff['funding_source'].map(funder_names)\n", + "dff = dff[['from_funder', 'display_name', 'total_amount_in_usd']]\n", + "dff" + ] + }, { "cell_type": "markdown", "id": "fe5ad20c-7772-4e94-83ec-77baea215d00", @@ -730,7 +1534,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 10, "id": "60aa05c7-098f-4e6f-8183-a01fc5ed9652", "metadata": {}, "outputs": [ @@ -896,7 +1700,7 @@ "9 537.338562 " ] }, - "execution_count": 8, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -929,7 +1733,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 11, "id": "fa50c103-7c3c-4fb2-bcb1-ff754a8b53f6", "metadata": {}, "outputs": [ @@ -963,8 +1767,8 @@ " \n", " 0\n", " optimism\n", - " 12\n", - " 240450291.744\n", + " 15\n", + " 275923907.037501\n", " \n", " \n", " 1\n", @@ -976,7 +1780,7 @@ " 2\n", " stellar\n", " 29\n", - " 32989032.98\n", + " 33589282.98\n", " \n", " \n", " 3\n", @@ -1001,16 +1805,16 @@ "" ], "text/plain": [ - " from_funder_name grant_pools amount_in_usd\n", - "0 optimism 12 240450291.744\n", - "1 arbitrumfoundation 1 122850952.0\n", - "2 stellar 29 32989032.98\n", - "3 octant-golemfoundation 5 3965429.51329\n", - "4 dao-drops-dorgtech 1 250001.0\n", - "5 clrfund 1 83028.740386" + " from_funder_name grant_pools amount_in_usd\n", + "0 optimism 15 275923907.037501\n", + "1 arbitrumfoundation 1 122850952.0\n", + "2 stellar 29 33589282.98\n", + "3 octant-golemfoundation 5 3965429.51329\n", + "4 dao-drops-dorgtech 1 250001.0\n", + "5 clrfund 1 83028.740386" ] }, - "execution_count": 9, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -1039,7 +1843,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 12, "id": "1bd3a7a8-8cac-420e-9e7b-5259ff0e3b2d", "metadata": {}, "outputs": [ @@ -1073,44 +1877,44 @@ " \n", " \n", " \n", - " 2142\n", + " 2249\n", " Qgbm336fY9862LN2Czg3UX04A3p7I/79Bv2M4D61DAI=\n", - " 8IKXraxq1pDuQD1xaDI20cjFrel55TZ/zf6LmP69qEg=\n", + " 1rc31e43WnXR31VM//z41gY2UFQfbo2b8KCwLw0rY4k=\n", " Gitcoin\n", - " efdevcon\n", - " 13.531599\n", + " rantomdotapp\n", + " 6131.318222\n", " \n", " \n", - " 2143\n", + " 2250\n", " Qgbm336fY9862LN2Czg3UX04A3p7I/79Bv2M4D61DAI=\n", - " 79HQoZtyZftibazh6Yz63aU06XODWs7b/9h4JAqPa1s=\n", + " DRZVxhlH8Qia/HQsZTqIe+hZVn/I0wjhgSpHqcNn0RE=\n", " Gitcoin\n", - " LexDAO\n", - " 86499.728685\n", + " eggcess-tech\n", + " 115.038641\n", " \n", " \n", - " 2144\n", - " 5Fgf9xv3CxTV+YbSShdY9XCJs7tgW8KNwQWq9rHUEsQ=\n", - " 79HQoZtyZftibazh6Yz63aU06XODWs7b/9h4JAqPa1s=\n", - " clr.fund\n", - " LexDAO\n", - " 193.952856\n", + " 2251\n", + " ta+k40iL4Aishk458IqTS4k+jcGiSCdYzpwaDPfKqss=\n", + " GFtPmpIWk2qUtklRVLF1k8VATmNH+3bHG4CA8iOfuxA=\n", + " Optimism\n", + " Yearn\n", + " 1597827.48\n", " \n", " \n", - " 2145\n", - " Qgbm336fY9862LN2Czg3UX04A3p7I/79Bv2M4D61DAI=\n", - " yEebFy4M1iAdb9+YQmdssSx9Qf+ZXfSVguL/JyidngI=\n", - " Gitcoin\n", - " DeFiEye\n", - " 224058.115245\n", + " 2252\n", + " IW0dZPkUh9+SEfZy8z8Om57ZGyjR3ZmSWkeojs9qnbU=\n", + " rU5cF8xxSnfmw0tq9VCl33LJXFCXqQVzqAWnWN9iWnw=\n", + " Arbitrum Foundation\n", + " Synapse\n", + " 3500000.0\n", " \n", " \n", - " 2146\n", - " 5Fgf9xv3CxTV+YbSShdY9XCJs7tgW8KNwQWq9rHUEsQ=\n", - " JQtLQErRk0u41xS292Cg+s3cRr8LaD5lQ2kME/Syp2Q=\n", - " clr.fund\n", - " Asilo Digital\n", - " 703.639308\n", + " 2253\n", + " ta+k40iL4Aishk458IqTS4k+jcGiSCdYzpwaDPfKqss=\n", + " rU5cF8xxSnfmw0tq9VCl33LJXFCXqQVzqAWnWN9iWnw=\n", + " Optimism\n", + " Synapse\n", + " 849991.175282\n", " \n", " \n", "\n", @@ -1118,28 +1922,28 @@ ], "text/plain": [ " from_project_id \\\n", - "2142 Qgbm336fY9862LN2Czg3UX04A3p7I/79Bv2M4D61DAI= \n", - "2143 Qgbm336fY9862LN2Czg3UX04A3p7I/79Bv2M4D61DAI= \n", - "2144 5Fgf9xv3CxTV+YbSShdY9XCJs7tgW8KNwQWq9rHUEsQ= \n", - "2145 Qgbm336fY9862LN2Czg3UX04A3p7I/79Bv2M4D61DAI= \n", - "2146 5Fgf9xv3CxTV+YbSShdY9XCJs7tgW8KNwQWq9rHUEsQ= \n", + "2249 Qgbm336fY9862LN2Czg3UX04A3p7I/79Bv2M4D61DAI= \n", + "2250 Qgbm336fY9862LN2Czg3UX04A3p7I/79Bv2M4D61DAI= \n", + "2251 ta+k40iL4Aishk458IqTS4k+jcGiSCdYzpwaDPfKqss= \n", + "2252 IW0dZPkUh9+SEfZy8z8Om57ZGyjR3ZmSWkeojs9qnbU= \n", + "2253 ta+k40iL4Aishk458IqTS4k+jcGiSCdYzpwaDPfKqss= \n", "\n", - " to_project_id funder project \\\n", - "2142 8IKXraxq1pDuQD1xaDI20cjFrel55TZ/zf6LmP69qEg= Gitcoin efdevcon \n", - "2143 79HQoZtyZftibazh6Yz63aU06XODWs7b/9h4JAqPa1s= Gitcoin LexDAO \n", - "2144 79HQoZtyZftibazh6Yz63aU06XODWs7b/9h4JAqPa1s= clr.fund LexDAO \n", - "2145 yEebFy4M1iAdb9+YQmdssSx9Qf+ZXfSVguL/JyidngI= Gitcoin DeFiEye \n", - "2146 JQtLQErRk0u41xS292Cg+s3cRr8LaD5lQ2kME/Syp2Q= clr.fund Asilo Digital \n", + " to_project_id funder \\\n", + "2249 1rc31e43WnXR31VM//z41gY2UFQfbo2b8KCwLw0rY4k= Gitcoin \n", + "2250 DRZVxhlH8Qia/HQsZTqIe+hZVn/I0wjhgSpHqcNn0RE= Gitcoin \n", + "2251 GFtPmpIWk2qUtklRVLF1k8VATmNH+3bHG4CA8iOfuxA= Optimism \n", + "2252 rU5cF8xxSnfmw0tq9VCl33LJXFCXqQVzqAWnWN9iWnw= Arbitrum Foundation \n", + "2253 rU5cF8xxSnfmw0tq9VCl33LJXFCXqQVzqAWnWN9iWnw= Optimism \n", "\n", - " amount \n", - "2142 13.531599 \n", - "2143 86499.728685 \n", - "2144 193.952856 \n", - "2145 224058.115245 \n", - "2146 703.639308 " + " project amount \n", + "2249 rantomdotapp 6131.318222 \n", + "2250 eggcess-tech 115.038641 \n", + "2251 Yearn 1597827.48 \n", + "2252 Synapse 3500000.0 \n", + "2253 Synapse 849991.175282 " ] }, - "execution_count": 10, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" }