diff --git a/autoagora/logs_db.py b/autoagora/logs_db.py index 6d38f0a..d276e74 100644 --- a/autoagora/logs_db.py +++ b/autoagora/logs_db.py @@ -2,8 +2,9 @@ # SPDX-License-Identifier: Apache-2.0 from dataclasses import dataclass -import asyncpg import graphql +import psycopg_pool +from psycopg import sql class LogsDB: @@ -16,7 +17,7 @@ class QueryStats: avg_time: float stddev_time: float - def __init__(self, pgpool: asyncpg.Pool) -> None: + def __init__(self, pgpool: psycopg_pool.AsyncConnectionPool) -> None: self.pgpool = pgpool def return_query_body(self, query): @@ -30,9 +31,11 @@ def return_query_body(self, query): async def get_most_frequent_queries( self, subgraph_ipfs_hash: str, min_count: int = 100 ): - async with self.pgpool.acquire() as connection: - rows = await connection.fetch( - """ + + async with self.pgpool.connection() as connection: + rows = await connection.execute( + sql.SQL( + """ SELECT query, count_id, @@ -54,22 +57,21 @@ async def get_most_frequent_queries( FROM query_logs WHERE - subgraph = $1 + subgraph = {hash} AND query_time_ms IS NOT NULL GROUP BY qhash HAVING - Count(id) >= $2 + Count(id) >= {min_count} ) as query_logs ON qhash = hash ORDER BY count_id DESC - """, - subgraph_ipfs_hash, - min_count, + """ + ).format(hash=subgraph_ipfs_hash, min_count=str(min_count)), ) - + rows = await rows.fetchall() return [ LogsDB.QueryStats( query=self.return_query_body(row[0]) diff --git a/autoagora/main.py b/autoagora/main.py index b88ddcc..2b51c2a 100644 --- a/autoagora/main.py +++ b/autoagora/main.py @@ -6,7 +6,7 @@ from dataclasses import dataclass from typing import Dict, Optional -import asyncpg +import psycopg_pool from prometheus_async.aio.web import start_http_server from autoagora.config import args, init_config @@ -39,15 +39,19 @@ async def allocated_subgraph_watcher(): # Initialize connection pool to PG database try: - pgpool = await asyncpg.create_pool( - host=args.postgres_host, - database=args.postgres_database, - user=args.postgres_username, - password=args.postgres_password, - port=args.postgres_port, - min_size=1, - max_size=args.postgres_max_connections, + conn_string = ( + f"host={args.postgres_host} " + f"dbname={args.postgres_database} " + f"user={args.postgres_username} " + f'password="{args.postgres_password}" ' + f"port={args.postgres_port}" ) + + pgpool = psycopg_pool.AsyncConnectionPool( + conn_string, min_size=1, max_size=args.postgres_max_connections, open=False + ) + await pgpool.open() + await pgpool.wait() assert pgpool except: logging.exception( diff --git a/autoagora/model_builder.py b/autoagora/model_builder.py index 03346dd..37d1676 100644 --- a/autoagora/model_builder.py +++ b/autoagora/model_builder.py @@ -6,7 +6,7 @@ import os from importlib.metadata import version -import asyncpg +import psycopg_pool from jinja2 import Template from autoagora.config import args @@ -15,7 +15,7 @@ from autoagora.utils.constants import AGORA_ENTRY_TEMPLATE -async def model_builder(subgraph: str, pgpool: asyncpg.Pool) -> str: +async def model_builder(subgraph: str, pgpool: psycopg_pool.AsyncConnectionPool) -> str: logs_db = LogsDB(pgpool) most_frequent_queries = await logs_db.get_most_frequent_queries(subgraph) model = build_template(subgraph, most_frequent_queries) diff --git a/autoagora/price_multiplier.py b/autoagora/price_multiplier.py index 5387b30..b4786d2 100644 --- a/autoagora/price_multiplier.py +++ b/autoagora/price_multiplier.py @@ -6,7 +6,7 @@ from datetime import datetime, timedelta, timezone from typing import Tuple -import asyncpg +import psycopg_pool from autoagora_agents.agent_factory import AgentFactory from prometheus_client import Gauge @@ -36,7 +36,9 @@ async def price_bandit_loop( - subgraph: str, pgpool: asyncpg.Pool, metrics_endpoints: MetricsEndpoints + subgraph: str, + pgpool: psycopg_pool.AsyncConnectionPool, + metrics_endpoints: MetricsEndpoints, ): try: # Instantiate environment. diff --git a/autoagora/price_save_state_db.py b/autoagora/price_save_state_db.py index fc5b3e1..330912c 100644 --- a/autoagora/price_save_state_db.py +++ b/autoagora/price_save_state_db.py @@ -5,7 +5,8 @@ from datetime import datetime, timezone from typing import Optional -import asyncpg +import psycopg_pool +from psycopg import sql @dataclass @@ -16,13 +17,13 @@ class SaveState: class PriceSaveStateDB: - def __init__(self, pgpool: asyncpg.Pool) -> None: + def __init__(self, pgpool: psycopg_pool.AsyncConnectionPool) -> None: self.pgpool = pgpool self._table_created = False async def _create_table_if_not_exists(self) -> None: if not self._table_created: - async with self.pgpool.acquire() as connection: + async with self.pgpool.connection() as connection: await connection.execute( # type: ignore """ CREATE TABLE IF NOT EXISTS price_save_state ( @@ -38,30 +39,34 @@ async def _create_table_if_not_exists(self) -> None: async def save_state(self, subgraph: str, mean: float, stddev: float): await self._create_table_if_not_exists() - async with self.pgpool.acquire() as connection: + async with self.pgpool.connection() as connection: await connection.execute( - """ + sql.SQL( + """ INSERT INTO price_save_state (subgraph, last_update, mean, stddev) - VALUES($1, $2, $3, $4) + VALUES({subgraph_hash}, {datetime}, {mean}, {stddev}) ON CONFLICT (subgraph) DO UPDATE SET - last_update = $2, - mean = $3, - stddev = $4 - """, - subgraph, - datetime.now(timezone.utc), - mean, - stddev, + last_update = {datetime}, + mean = {mean}, + stddev = {stddev} + """ + ).format( + subgraph_hash=subgraph, + datetime=str(datetime.now(timezone.utc)), + mean=mean, + stddev=stddev, + ) ) async def load_state(self, subgraph: str) -> Optional[SaveState]: await self._create_table_if_not_exists() - async with self.pgpool.acquire() as connection: - row = await connection.fetchrow( - """ + async with self.pgpool.connection() as connection: + row = await connection.execute( + sql.SQL( + """ SELECT last_update, mean, @@ -69,14 +74,14 @@ async def load_state(self, subgraph: str) -> Optional[SaveState]: FROM price_save_state WHERE - subgraph = $1 - """, - subgraph, + subgraph = {subgraph_hash} + """ + ).format(subgraph_hash=subgraph) ) - + row = await row.fetchone() if row: return SaveState( - last_update=row["last_update"], # type: ignore - mean=row["mean"], # type: ignore - stddev=row["stddev"], # type: ignore + last_update=row[0], # type: ignore + mean=row[1], # type: ignore + stddev=row[2], # type: ignore ) diff --git a/poetry.lock b/poetry.lock index d964775..30eed1b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -174,57 +174,6 @@ files = [ {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, ] -[[package]] -name = "asyncpg" -version = "0.27.0" -description = "An asyncio PostgreSQL driver" -category = "main" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "asyncpg-0.27.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fca608d199ffed4903dce1bcd97ad0fe8260f405c1c225bdf0002709132171c2"}, - {file = "asyncpg-0.27.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:20b596d8d074f6f695c13ffb8646d0b6bb1ab570ba7b0cfd349b921ff03cfc1e"}, - {file = "asyncpg-0.27.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a6206210c869ebd3f4eb9e89bea132aefb56ff3d1b7dd7e26b102b17e27bbb1"}, - {file = "asyncpg-0.27.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7a94c03386bb95456b12c66026b3a87d1b965f0f1e5733c36e7229f8f137747"}, - {file = "asyncpg-0.27.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bfc3980b4ba6f97138b04f0d32e8af21d6c9fa1f8e6e140c07d15690a0a99279"}, - {file = "asyncpg-0.27.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9654085f2b22f66952124de13a8071b54453ff972c25c59b5ce1173a4283ffd9"}, - {file = "asyncpg-0.27.0-cp310-cp310-win32.whl", hash = "sha256:879c29a75969eb2722f94443752f4720d560d1e748474de54ae8dd230bc4956b"}, - {file = "asyncpg-0.27.0-cp310-cp310-win_amd64.whl", hash = "sha256:ab0f21c4818d46a60ca789ebc92327d6d874d3b7ccff3963f7af0a21dc6cff52"}, - {file = "asyncpg-0.27.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:18f77e8e71e826ba2d0c3ba6764930776719ae2b225ca07e014590545928b576"}, - {file = "asyncpg-0.27.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c2232d4625c558f2aa001942cac1d7952aa9f0dbfc212f63bc754277769e1ef2"}, - {file = "asyncpg-0.27.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9a3a4ff43702d39e3c97a8786314123d314e0f0e4dabc8367db5b665c93914de"}, - {file = "asyncpg-0.27.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccddb9419ab4e1c48742457d0c0362dbdaeb9b28e6875115abfe319b29ee225d"}, - {file = "asyncpg-0.27.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:768e0e7c2898d40b16d4ef7a0b44e8150db3dd8995b4652aa1fe2902e92c7df8"}, - {file = "asyncpg-0.27.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:609054a1f47292a905582a1cfcca51a6f3f30ab9d822448693e66fdddde27920"}, - {file = "asyncpg-0.27.0-cp311-cp311-win32.whl", hash = "sha256:8113e17cfe236dc2277ec844ba9b3d5312f61bd2fdae6d3ed1c1cdd75f6cf2d8"}, - {file = "asyncpg-0.27.0-cp311-cp311-win_amd64.whl", hash = "sha256:bb71211414dd1eeb8d31ec529fe77cff04bf53efc783a5f6f0a32d84923f45cf"}, - {file = "asyncpg-0.27.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4750f5cf49ed48a6e49c6e5aed390eee367694636c2dcfaf4a273ca832c5c43c"}, - {file = "asyncpg-0.27.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:eca01eb112a39d31cc4abb93a5aef2a81514c23f70956729f42fb83b11b3483f"}, - {file = "asyncpg-0.27.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5710cb0937f696ce303f5eed6d272e3f057339bb4139378ccecafa9ee923a71c"}, - {file = "asyncpg-0.27.0-cp37-cp37m-win_amd64.whl", hash = "sha256:71cca80a056ebe19ec74b7117b09e650990c3ca535ac1c35234a96f65604192f"}, - {file = "asyncpg-0.27.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4bb366ae34af5b5cabc3ac6a5347dfb6013af38c68af8452f27968d49085ecc0"}, - {file = "asyncpg-0.27.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:16ba8ec2e85d586b4a12bcd03e8d29e3d99e832764d6a1d0b8c27dbbe4a2569d"}, - {file = "asyncpg-0.27.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d20dea7b83651d93b1eb2f353511fe7fd554752844523f17ad30115d8b9c8cd6"}, - {file = "asyncpg-0.27.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e56ac8a8237ad4adec97c0cd4728596885f908053ab725e22900b5902e7f8e69"}, - {file = "asyncpg-0.27.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bf21ebf023ec67335258e0f3d3ad7b91bb9507985ba2b2206346de488267cad0"}, - {file = "asyncpg-0.27.0-cp38-cp38-win32.whl", hash = "sha256:69aa1b443a182b13a17ff926ed6627af2d98f62f2fe5890583270cc4073f63bf"}, - {file = "asyncpg-0.27.0-cp38-cp38-win_amd64.whl", hash = "sha256:62932f29cf2433988fcd799770ec64b374a3691e7902ecf85da14d5e0854d1ea"}, - {file = "asyncpg-0.27.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fddcacf695581a8d856654bc4c8cfb73d5c9df26d5f55201722d3e6a699e9629"}, - {file = "asyncpg-0.27.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7d8585707ecc6661d07367d444bbaa846b4e095d84451340da8df55a3757e152"}, - {file = "asyncpg-0.27.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:975a320baf7020339a67315284a4d3bf7460e664e484672bd3e71dbd881bc692"}, - {file = "asyncpg-0.27.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2232ebae9796d4600a7819fc383da78ab51b32a092795f4555575fc934c1c89d"}, - {file = "asyncpg-0.27.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:88b62164738239f62f4af92567b846a8ef7cf8abf53eddd83650603de4d52163"}, - {file = "asyncpg-0.27.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:eb4b2fdf88af4fb1cc569781a8f933d2a73ee82cd720e0cb4edabbaecf2a905b"}, - {file = "asyncpg-0.27.0-cp39-cp39-win32.whl", hash = "sha256:8934577e1ed13f7d2d9cea3cc016cc6f95c19faedea2c2b56a6f94f257cea672"}, - {file = "asyncpg-0.27.0-cp39-cp39-win_amd64.whl", hash = "sha256:1b6499de06fe035cf2fa932ec5617ed3f37d4ebbf663b655922e105a484a6af9"}, - {file = "asyncpg-0.27.0.tar.gz", hash = "sha256:720986d9a4705dd8a40fdf172036f5ae787225036a7eb46e704c45aa8f62c054"}, -] - -[package.extras] -dev = ["Cython (>=0.29.24,<0.30.0)", "Sphinx (>=4.1.2,<4.2.0)", "flake8 (>=5.0.4,<5.1.0)", "pytest (>=6.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)", "uvloop (>=0.15.3)"] -docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] -test = ["flake8 (>=5.0.4,<5.1.0)", "uvloop (>=0.15.3)"] - [[package]] name = "attrs" version = "22.2.0" @@ -294,7 +243,7 @@ files = [ name = "backports-zoneinfo" version = "0.2.1" description = "Backport of the standard library zoneinfo module" -category = "dev" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1467,94 +1416,120 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] [[package]] name = "psycopg" -version = "3.1.8" +version = "3.1.12" description = "PostgreSQL database adapter for Python" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "psycopg-3.1.8-py3-none-any.whl", hash = "sha256:b1500c42063abaa01d30b056f0b300826b8dd8d586900586029a294ce74af327"}, - {file = "psycopg-3.1.8.tar.gz", hash = "sha256:59b4a71536b146925513c0234dfd1dc42b81e65d56ce5335dff4813434dbc113"}, + {file = "psycopg-3.1.12-py3-none-any.whl", hash = "sha256:8ec5230d6a7eb654b4fb3cf2d3eda8871d68f24807b934790504467f1deee9f8"}, + {file = "psycopg-3.1.12.tar.gz", hash = "sha256:cec7ad2bc6a8510e56c45746c631cf9394148bdc8a9a11fd8cf8554ce129ae78"}, ] [package.dependencies] "backports.zoneinfo" = {version = ">=0.2.0", markers = "python_version < \"3.9\""} -psycopg-binary = {version = ">=3.1.6,<=3.1.8", optional = true, markers = "extra == \"binary\""} +psycopg-binary = {version = "3.1.12", optional = true, markers = "extra == \"binary\""} typing-extensions = ">=4.1" tzdata = {version = "*", markers = "sys_platform == \"win32\""} [package.extras] -binary = ["psycopg-binary (>=3.1.6,<=3.1.8)"] -c = ["psycopg-c (>=3.1.6,<=3.1.8)"] -dev = ["black (>=22.3.0)", "dnspython (>=2.1)", "flake8 (>=4.0)", "mypy (>=0.990)", "types-setuptools (>=57.4)", "wheel (>=0.37)"] +binary = ["psycopg-binary (==3.1.12)"] +c = ["psycopg-c (==3.1.12)"] +dev = ["black (>=23.1.0)", "dnspython (>=2.1)", "flake8 (>=4.0)", "mypy (>=1.4.1)", "types-setuptools (>=57.4)", "wheel (>=0.37)"] docs = ["Sphinx (>=5.0)", "furo (==2022.6.21)", "sphinx-autobuild (>=2021.3.14)", "sphinx-autodoc-typehints (>=1.12)"] pool = ["psycopg-pool"] -test = ["mypy (>=0.990)", "pproxy (>=2.7)", "pytest (>=6.2.5)", "pytest-asyncio (>=0.17)", "pytest-cov (>=3.0)", "pytest-randomly (>=3.5)"] +test = ["anyio (>=3.6.2,<4.0)", "mypy (>=1.4.1)", "pproxy (>=2.7)", "pytest (>=6.2.5)", "pytest-cov (>=3.0)", "pytest-randomly (>=3.5)"] [[package]] name = "psycopg-binary" -version = "3.1.8" +version = "3.1.12" description = "PostgreSQL database adapter for Python -- C optimisation distribution" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "psycopg_binary-3.1.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f32684b4fc3863190c4b9c141342b2cbdb81632731b9c68e6946d772ba0560f2"}, - {file = "psycopg_binary-3.1.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37212244817b3cc7193ee4b5d60765c020ead5e53589c935d249bfb96452878b"}, - {file = "psycopg_binary-3.1.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f2563db6e44372f593a76c94452ce476306e0fb508e092f3fab4d9091a9974"}, - {file = "psycopg_binary-3.1.8-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b36fcc67d8b23935ee871a6331c9631ecfdb11452a64f34b8ecb9642de43aec8"}, - {file = "psycopg_binary-3.1.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8bb9f577a09e799322008e574a1671c5b2645e990f954be2b7dae669e3779750"}, - {file = "psycopg_binary-3.1.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ac81e68262b03163ca977f34448b4cadbc49db929146406b4706fe2141d76d1"}, - {file = "psycopg_binary-3.1.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fbfc9ae4edfb76c14d09bd70d6f399eb935008bbb3bc4cd6a4ab76645ba3443e"}, - {file = "psycopg_binary-3.1.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8602836138bc209aa5f9821c8e8439466f151c3ec4fcdbc740697e49cff1b920"}, - {file = "psycopg_binary-3.1.8-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:9cf94411f5a9064cf4ab1066976a7bce44f970f9603a01585c1040465eb312f9"}, - {file = "psycopg_binary-3.1.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a8fee8d846f9614331bd764850b4c1363730d36e88e14aa28ec4639318fd2093"}, - {file = "psycopg_binary-3.1.8-cp310-cp310-win_amd64.whl", hash = "sha256:2d5ae85c6037e45862e304d39ec24a24ddebc7d2b5b3601155dddc07c19c0cdc"}, - {file = "psycopg_binary-3.1.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17d187743d8ca63d24fa724bfee76e50b6473f1fef998cebcd35348b0d5936de"}, - {file = "psycopg_binary-3.1.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3762e73b6743139c5258d8b3a294edb309c691ba4f172c9f272315501390e7c2"}, - {file = "psycopg_binary-3.1.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87973d064a72bc2716309381b713f49f57c48100fb1f046943b780a04bc011f6"}, - {file = "psycopg_binary-3.1.8-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f8400d400f64f659a897d1ef67212012524cc44882bd24387515df9bb723364"}, - {file = "psycopg_binary-3.1.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f45766ce8e74eb456d8672116e936391e67290c50fd0cc1b41876b61261869b6"}, - {file = "psycopg_binary-3.1.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33ecf37c6348232073ea62b0630655479021f855635f72b4170693032993cdaf"}, - {file = "psycopg_binary-3.1.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:10b8f1f96f5e8f02a60ba76dab315d3e71cb76c18ff49aa18bbf48a8089c3202"}, - {file = "psycopg_binary-3.1.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:58cb0d007768dbccb67783baacf1c4016c7be8a494339a514321edee3d3b787a"}, - {file = "psycopg_binary-3.1.8-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:59d8dbea1bc3dbbc819c0320cb2b641dc362389b096098c62172f49605f58284"}, - {file = "psycopg_binary-3.1.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4325cee1641c25719bcf063f7683e909cb8cc9932ace3f8bf20ce112e47ce743"}, - {file = "psycopg_binary-3.1.8-cp311-cp311-win_amd64.whl", hash = "sha256:064502d191d7bc32a48670cc605ce49abcdb5e01e2697ee3fe546cff330fb8ae"}, - {file = "psycopg_binary-3.1.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5fd8492931865cc7181169b2dbf472377a5b5808f001e73f5c25b05bb61e9622"}, - {file = "psycopg_binary-3.1.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4d1a4ea2ca20f0bc944bc28e4addb80e6a22ac60a85fc7035e57c88e96f3a18"}, - {file = "psycopg_binary-3.1.8-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c27be5ddf4a05146ae7fb8429e9367dad0dc278a7d0e2f5094dd533195c4f8a1"}, - {file = "psycopg_binary-3.1.8-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa8ca48a35be0f9880ed2093c213f07d318fa9389a2b9194196c239e41a77841"}, - {file = "psycopg_binary-3.1.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf59e1d06f420930fc4c16a42ed6476c60c83976c82e53012dbca45f009d5978"}, - {file = "psycopg_binary-3.1.8-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:cb3013b76cbab4a903f3b9c87f4518335627cb05fd89f9e04520c1743c2b919b"}, - {file = "psycopg_binary-3.1.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:db84eaa9e2d13e37a97dcd39d2fe78e0a3052c9aa67b5f0b4f3d346a155f4d21"}, - {file = "psycopg_binary-3.1.8-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:2c3d268cf2dbb79e52a555c2e7b26c6df2d014f3fb918d512ffc25ecc9c54582"}, - {file = "psycopg_binary-3.1.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0fe6205af5f63ee6e4816b267bf06add5934a259cddcf7dfdfc8ed738f5127b2"}, - {file = "psycopg_binary-3.1.8-cp37-cp37m-win_amd64.whl", hash = "sha256:f99806a5b9a5ba5cb5f46a0fa0440cd721556e0af09a7cadcc39e27ae9b1807e"}, - {file = "psycopg_binary-3.1.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0cc5d5a9b0acbf38e0b4de1c701d235f0cb750ef3de528dedfdbab1a367f2396"}, - {file = "psycopg_binary-3.1.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:478ecbb774398e5df6ee365a4d0a77f382a65f140e76720909804255c7801d4a"}, - {file = "psycopg_binary-3.1.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b40b56c5b3ffa8481f7bebb08473602ddb8e2e86ba25bf9261ba428eb7887175"}, - {file = "psycopg_binary-3.1.8-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:37df8714837d2c701ba4c54462a189b95d1a4439d4d147fb71018560e9a60547"}, - {file = "psycopg_binary-3.1.8-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29a38b48cbec8484d83efea4d1d0707e49a3c51a2273cfbaa3d9ba280d3df7d9"}, - {file = "psycopg_binary-3.1.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1a2209ef4df25f4ed8d91924bd4d9c7028d254e61216366c4b894c8a6ea4f88"}, - {file = "psycopg_binary-3.1.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:858a794c2d5e984627503581f03cc68cef97ee080993b7b6a0b7b30cb4fac107"}, - {file = "psycopg_binary-3.1.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:574c8b7b51e8d5c06f27125fc218d1328c018c0c1ad8f1202033aa6897b8ee99"}, - {file = "psycopg_binary-3.1.8-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:e3dc783eedde10f966039ecc5f96f7df25c288ea4f6795d28b990f312c33ff09"}, - {file = "psycopg_binary-3.1.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:94f9e7ccbfdba1c4f5de80b615187eb47a351ab64a9123d87aea4bf347c1e1d8"}, - {file = "psycopg_binary-3.1.8-cp38-cp38-win_amd64.whl", hash = "sha256:1425c2cc4cfd4778d9dee578541f11546a93fc2f5c558a0411c94026a1cf94c7"}, - {file = "psycopg_binary-3.1.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e68e8b8077cd45dd2683fcd9a384e7672b400e26c0c7d04dac0cf0763c12be78"}, - {file = "psycopg_binary-3.1.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:60b22dd46e4e4f678379cf3388468171c2ecea74e90b1332d173ffa8cd83315f"}, - {file = "psycopg_binary-3.1.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61a1ccef7e0bf6128a7818c9d22cc850cf7649cee9541e82e4a8c080a734024d"}, - {file = "psycopg_binary-3.1.8-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e7a7b41eba96c7b9648efee57298f1aa0d96e081dea76489f52113536981712"}, - {file = "psycopg_binary-3.1.8-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a161785b1c8e26cd8e8d5436fa39ba2a8af590c17f1741aae11f8076a08485e6"}, - {file = "psycopg_binary-3.1.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a978d2bea09265eb6ebcd1b8a3aa05ea4118aa4013cb9669e12a8656975385cd"}, - {file = "psycopg_binary-3.1.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:251d2e6dca112dd359c029f422a025d75e78f2f2af4a2aceff506fdc5120f5f9"}, - {file = "psycopg_binary-3.1.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a1f052642a54eda53786fa8b72fca2e48ceaf0fc2f3e8709c87694fd7c45ac50"}, - {file = "psycopg_binary-3.1.8-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:73747e6a5dfb05500ff3857f9b9ee50e4f4f663250454d773b98d818545f10fa"}, - {file = "psycopg_binary-3.1.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:811d870ca9e97875db92f9b346492c4fa7a9edd74dce3604015dd13389fef46a"}, - {file = "psycopg_binary-3.1.8-cp39-cp39-win_amd64.whl", hash = "sha256:8a0f425171e95379f1fe93b41d67c6dfe85b6b635944facf07ca26ff7fa8ab1d"}, + {file = "psycopg_binary-3.1.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29a69f62aae8617361376d9ed1e34966ae9c3a74c4ab3aa430a7ce0c11530862"}, + {file = "psycopg_binary-3.1.12-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7308316fdb6796399041b80db0ab9f356504ed26427e46834ade82ba94b067ce"}, + {file = "psycopg_binary-3.1.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130752b9b2f8d071f179e257b9698cedfe4546be81ad5ecd8ed52cf9d725580d"}, + {file = "psycopg_binary-3.1.12-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:45bcecc96a6e6fe11e06b75f7ba8005d6f717f16fae7ab1cf5a0aec5191f87c3"}, + {file = "psycopg_binary-3.1.12-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc3f0fcc4fcccffda2450c725bee9fad73bc6c110cfbe3b8a777063845d9c6b9"}, + {file = "psycopg_binary-3.1.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f93749f0fe69cfbfec22af690bb4b241f1a4347c57be26fe2e5b70588f7d602f"}, + {file = "psycopg_binary-3.1.12-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:36147f708cc6a9d74c2b8d880f8dd3a6d53364b5c487536adaa022d435c90733"}, + {file = "psycopg_binary-3.1.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:2bbcc6fbabc2b92d18d955d9fa104fd9d8bd2dcb97a279c4e788c6b714ffd1af"}, + {file = "psycopg_binary-3.1.12-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0dee8a1ecc501d9c3db06d08184712459bbb5806a09121c3a25e8cbe91e234d7"}, + {file = "psycopg_binary-3.1.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:49d6acf228edb5bd9000735b89b780b18face776d081b905cf68e149d57dfcc1"}, + {file = "psycopg_binary-3.1.12-cp310-cp310-win_amd64.whl", hash = "sha256:ee65335781a54f29f4abc28060a6188c41bdd42fdc3cbc1dd84695ed8ef18321"}, + {file = "psycopg_binary-3.1.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d401722aa38bda64d1ba8293f6dad99f6f684711e2c016a93f138f2bbcff2a4b"}, + {file = "psycopg_binary-3.1.12-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:46eac158e8e794d9414a8fe7706beeee9b1ecc4accbea914314825ace8137105"}, + {file = "psycopg_binary-3.1.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f017400679aa38f6cb22b888b8ec198a5b100ec2132e6b3bcfa797b14b5b438"}, + {file = "psycopg_binary-3.1.12-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d176c4614f5208ab9938d5426d61627c8fbc7f8dab53fef42c8bf2ab8605aa51"}, + {file = "psycopg_binary-3.1.12-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c48c4f3fcfd9e75e3fdb18eea320de591e06059a859280ec26ce8d753299353d"}, + {file = "psycopg_binary-3.1.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98fce28d8136bdd883f20d26467bf259b5fb559eb64d8f83695690714cdfdad3"}, + {file = "psycopg_binary-3.1.12-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4a0f44bc29fc1b56ee1c865796cbe354078ee1e985f898e4915db185055bf7d"}, + {file = "psycopg_binary-3.1.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6def4f238ca02d6b42336b405d02729c081c978cda9b6ba7549a9c63a91ba823"}, + {file = "psycopg_binary-3.1.12-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:000838cb5ab7851116b462e58893a96b0f1e35864135a6283f3242a730ec45d3"}, + {file = "psycopg_binary-3.1.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7949e1aefe339f04dbecac6aa036c9cd137a58f966c4b96ab933823c340ee12"}, + {file = "psycopg_binary-3.1.12-cp311-cp311-win_amd64.whl", hash = "sha256:b32922872460575083487de41e17e8cf308c3550da02c704efe42960bc6c19de"}, + {file = "psycopg_binary-3.1.12-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:70054ada2f890d004dc3d5ff908e34aecb085fd599d40db2975c09a39c50dfc3"}, + {file = "psycopg_binary-3.1.12-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7544d6d74f5b5f9daafe8a4ed7d266787d62a2bf16f5120c45d42d1f4a856bc8"}, + {file = "psycopg_binary-3.1.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43197161099cb4e36a9ca44c10657908b619d7263ffcff30932ad4627430dc3c"}, + {file = "psycopg_binary-3.1.12-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:68398cdf3aedd4042b1126b9aba34615f1ab592831483282f19f0159fce5ca75"}, + {file = "psycopg_binary-3.1.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77ae6cda3ffee2425aca9ea7af57296d0c701e2ac5897b48b95dfee050234592"}, + {file = "psycopg_binary-3.1.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:278e8888e90fb6ebd7eae8ccb85199eafd712b734e641e0d40f2a903e946102d"}, + {file = "psycopg_binary-3.1.12-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:047c4ba8d3089465b0a69c4c669128df43403867858d78da6b40b33788bfa89f"}, + {file = "psycopg_binary-3.1.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8248b11ac490bb74de80457ab0e9cef31c08164ff7b867031927a17e5c9e19ed"}, + {file = "psycopg_binary-3.1.12-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6979c02acb9783c6134ee516751b8f891a2d4db7f73ebecc9e92750283d6fb99"}, + {file = "psycopg_binary-3.1.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:eaf2375b724ad61ee82a5c2a849e57b12b3cb510ec8845084132bbb907cb3335"}, + {file = "psycopg_binary-3.1.12-cp312-cp312-win_amd64.whl", hash = "sha256:6177cfa6f872a9cc84dbfc7dc163af6ef01639c50acc9a441673f29c2305c37a"}, + {file = "psycopg_binary-3.1.12-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b81427fd5a97c9b4ac12f3b8d985870b0c3866b5fc2e72e51cacd3630ffd6466"}, + {file = "psycopg_binary-3.1.12-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f17a2c393879aa54f840540009d0e70a30d22ffa0038d81e258ac2c99b15d74"}, + {file = "psycopg_binary-3.1.12-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c6a5d125a61101ef5ab7384206e43952fe2a5fca997b96d28a28a752512f900"}, + {file = "psycopg_binary-3.1.12-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:942a18df448a33d77aa7dff7e93062ace7926608a965db003622cb5f27910ba2"}, + {file = "psycopg_binary-3.1.12-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3195baff3e3e5d71828400d38af0ffc5a15d7dca2bfaadc9eb615235774b9290"}, + {file = "psycopg_binary-3.1.12-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f26bb34e0e9bb83fba00c4835f91f5c5348cdf689df8c8b503571c0d0027c8f5"}, + {file = "psycopg_binary-3.1.12-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:104bdc85c5c4884b3f900155b635588a28740f561b32a3e27c38bcd249feba41"}, + {file = "psycopg_binary-3.1.12-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:53464cb71e06faac479f44b8870f115004187e1dfb299b9725d1d7f85d9e5479"}, + {file = "psycopg_binary-3.1.12-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:052835aac03ee6a9d5b6fe35c468da79084ebe38709e6d3c24ff5b9422fb2947"}, + {file = "psycopg_binary-3.1.12-cp37-cp37m-win_amd64.whl", hash = "sha256:a21a7fffec1a225b26d72adb960d771fc5a9aba8e1f7dd710abcaa9a980e9740"}, + {file = "psycopg_binary-3.1.12-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6925a543e88cdfd1a2f679c7a33c08f107de60728a4a3c52f88d4491d40a7f51"}, + {file = "psycopg_binary-3.1.12-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b04957bd5caff94eac38306357b6d448dd20a6f68fd998e115e3731a55118d83"}, + {file = "psycopg_binary-3.1.12-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6f55979804853efa5ce84d7ef59ff3772e0823247497f7d4a6870e6527fd791"}, + {file = "psycopg_binary-3.1.12-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d343e1f564fdc8964e1c08b8a6c1f6ebf4b45ee5631b5241c9cbac793f4500c"}, + {file = "psycopg_binary-3.1.12-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:48c4ba35f717783327931aa9da6e6aab81b6b90f3e6b902b18e269d73e7d0882"}, + {file = "psycopg_binary-3.1.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d77c95d6086e0714225764772bf8110bb29dfbc6c32aa56e725a01998ce20e7c"}, + {file = "psycopg_binary-3.1.12-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6dea80e65c7a97150d555b64744e7279ff4c6b259d27580b756a5b282a7d44e3"}, + {file = "psycopg_binary-3.1.12-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:03a851123d0155e1d6ca5b6cccf624e2fc71c8f7eae76f5100196e0fca047d30"}, + {file = "psycopg_binary-3.1.12-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:99ad07b9ef5853713bb63c55e179af52994e96f445c5d66b87d8b986182922ef"}, + {file = "psycopg_binary-3.1.12-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4441d0f8ecae499a6ac5c79078c9fcd406c0bf70e72cb6cba888aca51aa46943"}, + {file = "psycopg_binary-3.1.12-cp38-cp38-win_amd64.whl", hash = "sha256:cb45a709b966583773acc3418fffbf6d73b014943b6efceca6a7d3ca960956cf"}, + {file = "psycopg_binary-3.1.12-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5112245daf98e22046316e72690689a8952a9b078908206a6b16cd28d84cde7c"}, + {file = "psycopg_binary-3.1.12-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2eb94bf0bd653c940517cd92dc4f98c85d505f69013b247dda747413bcf0a8b"}, + {file = "psycopg_binary-3.1.12-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d41b03ce52a109858735ac19fe0295e3f77bef0388d6a3e105074ad68f4a9645"}, + {file = "psycopg_binary-3.1.12-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4fddc3c9beaf745de3da10230f0144a4c667b21c3f7a94a3bb1fb004954c9810"}, + {file = "psycopg_binary-3.1.12-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5987616698c895ae079fb5e26811b72948cb3b75c2c690446379298e96c1568"}, + {file = "psycopg_binary-3.1.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4ae45d58bd79795a2d23d05be5496b226b09ac2688b9ed9808e13c345e2d542"}, + {file = "psycopg_binary-3.1.12-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb98252ac8ba41a121f88979e4232ffc1d6722c953531cbdae2b328322308581"}, + {file = "psycopg_binary-3.1.12-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ca09e4937c9db24a58951ee9aea7aae7bca11a954b30c59f3b271e9bdebd80d7"}, + {file = "psycopg_binary-3.1.12-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:03e321e149d051daa20892ed1bb3beabf0aae98a8c37da30ec80fa12306f9ba9"}, + {file = "psycopg_binary-3.1.12-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d819cb43cccc10ba501b9d462409fcaaeb19f77b8379b2e7ca0ced4a49446d4a"}, + {file = "psycopg_binary-3.1.12-cp39-cp39-win_amd64.whl", hash = "sha256:c9eb2ba27760bc1303f0708ba95b9e4f3f3b77a081ef4f7f53375c71da3a1bee"}, +] + +[[package]] +name = "psycopg-pool" +version = "3.2.0" +description = "Connection Pool for Psycopg" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "psycopg-pool-3.2.0.tar.gz", hash = "sha256:2e857bb6c120d012dba240e30e5dff839d2d69daf3e962127ce6b8e40594170e"}, + {file = "psycopg_pool-3.2.0-py3-none-any.whl", hash = "sha256:73371d4e795d9363c7b496cbb2dfce94ee8fbf2dcdc384d0a937d1d9d8bdd08d"}, ] +[package.dependencies] +typing-extensions = ">=3.10" + [[package]] name = "pyasn1" version = "0.4.8" @@ -2224,7 +2199,7 @@ files = [ name = "tzdata" version = "2022.7" description = "Provider of IANA time zone data" -category = "dev" +category = "main" optional = false python-versions = ">=2" files = [ @@ -2520,4 +2495,4 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.11" -content-hash = "93604446e784569369a8ba32231a5ce19dbb38d5dcda1701899178abc741a17c" +content-hash = "0902d909becd11729648b9d6c1448788959728a3c57caa7b6c17175baf59a95d" diff --git a/pyproject.toml b/pyproject.toml index 4eaa2bb..28db450 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,13 +30,14 @@ graphql-core = "^3.2.0" base58 = "^2.1.1" aiohttp = "^3.8.1" gql = {extras = ["aiohttp"], version = "^3.2.0"} -asyncpg = "^0.27.0" prometheus-async = {extras = ["aiohttp"], version = "^22.1.0"} backoff = "^2.2.1" python-json-logger = "^2.0.4" autoagora-agents = {git = "https://github.com/semiotic-ai/autoagora-agents.git", rev = "v1.2.1"} kubernetes = "^26.1.0" jinja2 = "^3.1.2" +psycopg = "^3.1.12" +psycopg-pool = "^3.2.0" [tool.poetry.group.dev.dependencies] black = "^22.1.0" diff --git a/tests/test_logs_db.py b/tests/test_logs_db.py index 9145a69..955998b 100644 --- a/tests/test_logs_db.py +++ b/tests/test_logs_db.py @@ -1,4 +1,4 @@ -import asyncpg +import psycopg_pool import pytest from autoagora.logs_db import LogsDB @@ -7,50 +7,55 @@ class TestLogsDB: @pytest.fixture async def pgpool(self, postgresql): - pool = await asyncpg.create_pool( - host=postgresql.info.host, - database=postgresql.info.dbname, - user=postgresql.info.user, - password=postgresql.info.password, - port=postgresql.info.port, + conn_string = ( + f"host={postgresql.info.host} " + f"dbname={postgresql.info.dbname} " + f"user={postgresql.info.user} " + f'password="{postgresql.info.password}" ' + f"port={postgresql.info.port}" ) - assert pool - await pool.execute( + + pool = psycopg_pool.AsyncConnectionPool( + conn_string, min_size=2, max_size=10, open=False + ) + await pool.open() + await pool.wait() + async with pool.connection() as conn: + await conn.execute( + """ + CREATE TABLE query_skeletons ( + hash BYTEA PRIMARY KEY, + query TEXT NOT NULL + ) """ - CREATE TABLE query_skeletons ( - hash BYTEA PRIMARY KEY, - query TEXT NOT NULL ) - """ - ) - await pool.execute( + await conn.execute( + """ + CREATE TABLE query_logs ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + query_hash BYTEA REFERENCES query_skeletons(hash), + subgraph CHAR(46) NOT NULL, + timestamp TIMESTAMPTZ NOT NULL, + query_time_ms INTEGER, + query_variables TEXT + ) """ - CREATE TABLE query_logs ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - query_hash BYTEA REFERENCES query_skeletons(hash), - subgraph CHAR(46) NOT NULL, - timestamp TIMESTAMPTZ NOT NULL, - query_time_ms INTEGER, - query_variables TEXT - ) - """ - ) - await pool.execute( + await conn.execute( + """ + INSERT INTO query_skeletons (hash, query) + VALUES ('hash1', 'query getData{ values { id } }'), ('hash2', 'query getInfo{ info { id text} }') """ - INSERT INTO query_skeletons (hash, query) - VALUES ('hash1', 'query getData{ values { id } }'), ('hash2', 'query getInfo{ info { id text} }') - """ - ) - await pool.execute( + ) + await conn.execute( + """ + INSERT INTO query_logs (query_hash, subgraph, timestamp, query_time_ms) + VALUES ('hash1', 'QmPnu3R7Fm4RmBF21aCYUohDmWbKd3VMXo64ACiRtwUQrn', '2023-05-18T21:47:41+00:00', 100), + ('hash1', 'QmPnu3R7Fm4RmBF21aCYUohDmWbKd3VMXo64ACiRtwUQrn', '2023-05-18T21:47:41+00:00', 200), + ('hash2', 'QmTJBvvpknMow6n4YU8R9Swna6N8mHK8N2WufetysBiyuL', '2023-05-18T21:47:41+00:00', 50), + ('hash1', 'QmTJBvvpknMow6n4YU8R9Swna6N8mHK8N2WufetysBiyuL', '2023-05-18T21:47:41+00:00', 10) """ - INSERT INTO query_logs (query_hash, subgraph, timestamp, query_time_ms) - VALUES ('hash1', 'QmPnu3R7Fm4RmBF21aCYUohDmWbKd3VMXo64ACiRtwUQrn', '2023-05-18T21:47:41+00:00', 100), - ('hash1', 'QmPnu3R7Fm4RmBF21aCYUohDmWbKd3VMXo64ACiRtwUQrn', '2023-05-18T21:47:41+00:00', 200), - ('hash2', 'QmTJBvvpknMow6n4YU8R9Swna6N8mHK8N2WufetysBiyuL', '2023-05-18T21:47:41+00:00', 50), - ('hash1', 'QmTJBvvpknMow6n4YU8R9Swna6N8mHK8N2WufetysBiyuL', '2023-05-18T21:47:41+00:00', 10) - """ - ) + ) yield pool await pool.close() diff --git a/tests/test_model_builder.py b/tests/test_model_builder.py index 98eedfa..9f8046a 100644 --- a/tests/test_model_builder.py +++ b/tests/test_model_builder.py @@ -3,34 +3,70 @@ import tempfile from unittest import mock -import asyncpg -import pytest - -from autoagora import model_builder from autoagora.config import init_config from autoagora.logs_db import LogsDB +from autoagora.model_builder import apply_default_model, build_template from tests.utils.constants import TEST_MANUAL_AGORA_ENTRY, TEST_QUERY_1, TEST_QUERY_2 class TestModelBuilder: - @pytest.fixture - async def pgpool(self, postgresql): - pool = await asyncpg.create_pool( - host=postgresql.info.host, - database=postgresql.info.dbname, - user=postgresql.info.user, - password=postgresql.info.password, - port=postgresql.info.port, + async def test_build_model(self, postgresql): + init_config( + [ + "--indexer-agent-mgmt-endpoint", + "http://nowhere", + "--postgres-host", + postgresql.info.host, + "--postgres-username", + postgresql.info.user, + "--postgres-password", + postgresql.info.password, + "--postgres-port", + str(postgresql.info.port), + "--postgres-database", + postgresql.info.dbname, + "--indexer-service-metrics-endpoint", + "http://indexer-service.default.svc.cluster.local:7300/metrics", + ] + ) + most_frequent_queries = [ + LogsDB.QueryStats( + query=TEST_QUERY_1, + count=100, + min_time=1, + max_time=60, + avg_time=1.2, + stddev_time=0.5, + ), + LogsDB.QueryStats( + query=TEST_QUERY_2, + count=10, + min_time=3, + max_time=20, + avg_time=13.2, + stddev_time=0.7, + ), + ] + + model = build_template( + "Qmadj8x9km1YEyKmRnJ6EkC2zpJZFCfTyTZpuqC3j6e1QH", most_frequent_queries ) - assert pool - yield pool - await pool.close() + pattern = r"# Generated by AutoAgora \d+\.\d+\.\d+" + # To ensure a version is being obtained + assert re.match(pattern, model), f"{model} does not match pattern {pattern}" + assert TEST_QUERY_1 in model + assert TEST_QUERY_2 in model + assert TEST_MANUAL_AGORA_ENTRY not in model - async def test_build_model(self, pgpool, postgresql): - with mock.patch( - "autoagora.logs_db.LogsDB.get_most_frequent_queries" - ) as mock_get_mfq: - mock_get_mfq.return_value = [ + async def test_build_model_with_manual_entry(self, postgresql): + subgraph = "Qmadj8x9km1YEyKmRnJ6EkC2zpJZFCfTyTZpuqC3j6e1QH" + file_type = ".agora" + # Creates a temp dir to simulate manual entries + with tempfile.TemporaryDirectory() as temp_dir: + # Create a file inside temp dir which will be deleted once out of context + with open(os.path.join(temp_dir, subgraph + file_type), "w") as temp_file: + temp_file.write(TEST_MANUAL_AGORA_ENTRY) + most_frequent_queries = [ LogsDB.QueryStats( query=TEST_QUERY_1, count=100, @@ -64,78 +100,19 @@ async def test_build_model(self, pgpool, postgresql): postgresql.info.dbname, "--indexer-service-metrics-endpoint", "http://indexer-service.default.svc.cluster.local:7300/metrics", + "--manual-entry-path", + temp_dir, ] ) - model = await model_builder.model_builder( - "Qmadj8x9km1YEyKmRnJ6EkC2zpJZFCfTyTZpuqC3j6e1QH", pgpool - ) + model = build_template(subgraph, most_frequent_queries) pattern = r"# Generated by AutoAgora \d+\.\d+\.\d+" # To ensure a version is being obtained assert re.match(pattern, model), f"{model} does not match pattern {pattern}" assert TEST_QUERY_1 in model assert TEST_QUERY_2 in model - assert TEST_MANUAL_AGORA_ENTRY not in model - - async def test_build_model_with_manual_entry(self, pgpool, postgresql): - subgraph = "Qmadj8x9km1YEyKmRnJ6EkC2zpJZFCfTyTZpuqC3j6e1QH" - file_type = ".agora" - # Creates a temp dir to simulate manual entries - with tempfile.TemporaryDirectory() as temp_dir: - # Create a file inside temp dir which will be deleted once out of context - with open(os.path.join(temp_dir, subgraph + file_type), "w") as temp_file: - temp_file.write(TEST_MANUAL_AGORA_ENTRY) - with mock.patch( - "autoagora.logs_db.LogsDB.get_most_frequent_queries" - ) as mock_get_mfq: - mock_get_mfq.return_value = [ - LogsDB.QueryStats( - query=TEST_QUERY_1, - count=100, - min_time=1, - max_time=60, - avg_time=1.2, - stddev_time=0.5, - ), - LogsDB.QueryStats( - query=TEST_QUERY_2, - count=10, - min_time=3, - max_time=20, - avg_time=13.2, - stddev_time=0.7, - ), - ] - init_config( - [ - "--indexer-agent-mgmt-endpoint", - "http://nowhere", - "--postgres-host", - postgresql.info.host, - "--postgres-username", - postgresql.info.user, - "--postgres-password", - postgresql.info.password, - "--postgres-port", - str(postgresql.info.port), - "--postgres-database", - postgresql.info.dbname, - "--indexer-service-metrics-endpoint", - "http://indexer-service.default.svc.cluster.local:7300/metrics", - "--manual-entry-path", - temp_dir, - ] - ) - model = await model_builder.model_builder(subgraph, pgpool) - pattern = r"# Generated by AutoAgora \d+\.\d+\.\d+" - # To ensure a version is being obtained - assert re.match( - pattern, model - ), f"{model} does not match pattern {pattern}" - assert TEST_QUERY_1 in model - assert TEST_QUERY_2 in model - assert TEST_MANUAL_AGORA_ENTRY in model + assert TEST_MANUAL_AGORA_ENTRY in model - async def test_apply_default_model(self, pgpool, postgresql): + async def test_apply_default_model(self, postgresql): subgraph = "Qmadj8x9km1YEyKmRnJ6EkC2zpJZFCfTyTZpuqC3j6e1QH" file_type = ".agora" # Creates a temp dir to simulate manual entries @@ -168,7 +145,7 @@ async def test_apply_default_model(self, pgpool, postgresql): temp_dir, ] ) - await model_builder.apply_default_model(subgraph) + await apply_default_model(subgraph) # Obtain the args send to the logger.debug fn debug_logs_args = logging_debug_mock.call_args[0] # Remove \n since they cause the assertion to bug and fail diff --git a/tests/test_price_multiplier.py b/tests/test_price_multiplier.py index b16af8a..acdbde6 100644 --- a/tests/test_price_multiplier.py +++ b/tests/test_price_multiplier.py @@ -2,7 +2,7 @@ from datetime import datetime, timedelta, timezone from unittest import mock -import asyncpg +import psycopg_pool import pytest import autoagora.price_multiplier as price_multiplier @@ -18,25 +18,32 @@ class TestPriceMultiplier: @pytest.fixture async def pgpool(self, postgresql): - pool = await asyncpg.create_pool( - host=postgresql.info.host, - database=postgresql.info.dbname, - user=postgresql.info.user, - password=postgresql.info.password, - port=postgresql.info.port, + conn_string = ( + f"host={postgresql.info.host} " + f"dbname={postgresql.info.dbname} " + f"user={postgresql.info.user} " + f'password="{postgresql.info.password}" ' + f"port={postgresql.info.port}" ) - assert pool - await pool.execute( - """ - CREATE TABLE IF NOT EXISTS price_save_state ( - subgraph char(46) PRIMARY KEY, - last_update timestamptz NOT NULL, - mean double precision NOT NULL, - stddev double precision NOT NULL - ) - """ + + pool = psycopg_pool.AsyncConnectionPool( + conn_string, min_size=2, max_size=10, open=False ) + await pool.open() + await pool.wait() + async with pool.connection() as conn: + await conn.execute( + """ + CREATE TABLE IF NOT EXISTS price_save_state ( + subgraph char(46) PRIMARY KEY, + last_update timestamptz NOT NULL, + mean double precision NOT NULL, + stddev double precision NOT NULL + ) + """ + ) yield pool + await pool.close() async def test_price_bandit_loop(self, pgpool): subgraph = "QmTJBvvpknMow6n4YU8R9Swna6N8mHK8N2WufetysBiyuL" @@ -104,12 +111,13 @@ async def test_restore_from_save_state(self, pgpool): stddev = 0.3 time_delta = timedelta(days=3) save_state = PriceSaveStateDB(pgpool) - await pgpool.execute( - """ - INSERT INTO price_save_state (subgraph, last_update, mean, stddev) - VALUES ('QmTJBvvpknMow6n4YU8R9Swna6N8mHK8N2WufetysBiyuL', '2023-05-18T21:47:41+00:00', 0.3, 0.2) - """ - ) + async with pgpool.connection() as conn: + await conn.execute( + """ + INSERT INTO price_save_state (subgraph, last_update, mean, stddev) + VALUES ('QmTJBvvpknMow6n4YU8R9Swna6N8mHK8N2WufetysBiyuL', '2023-05-18T21:47:41+00:00', 0.3, 0.2) + """ + ) time_to_compare = datetime.strptime( "2023-05-19T21:47:41+GMT", "%Y-%m-%dT%H:%M:%S+%Z" ).replace(tzinfo=timezone.utc) diff --git a/tests/test_price_save_state_db.py b/tests/test_price_save_state_db.py index 747cec0..69e68cb 100644 --- a/tests/test_price_save_state_db.py +++ b/tests/test_price_save_state_db.py @@ -1,7 +1,7 @@ import random import string -import asyncpg +import psycopg_pool import pytest from autoagora_agents.agent_factory import AgentFactory from numpy.testing import assert_approx_equal @@ -11,18 +11,27 @@ class TestPriceSaveStateDB: @pytest.fixture - async def pssdb(self, postgresql): - pgpool = await asyncpg.create_pool( - host=postgresql.info.host, - database=postgresql.info.dbname, - user=postgresql.info.user, - password=postgresql.info.password, - port=postgresql.info.port, + async def pgpool(self, postgresql): + conn_string = ( + f"host={postgresql.info.host} " + f"dbname={postgresql.info.dbname} " + f"user={postgresql.info.user} " + f'password="{postgresql.info.password}" ' + f"port={postgresql.info.port}" ) - assert pgpool + pool = psycopg_pool.AsyncConnectionPool( + conn_string, min_size=2, max_size=10, open=False + ) + await pool.open() + await pool.wait() + yield pool + await pool.close() + + @pytest.fixture + async def pssdb(self, pgpool): pssdb_ = price_save_state_db.PriceSaveStateDB(pgpool) - return pssdb_ + yield pssdb_ async def test_create_write_read(self, pssdb): random.seed(42)