diff --git a/.env.example b/.env.example index 78bcb7a..00336cc 100644 --- a/.env.example +++ b/.env.example @@ -1,8 +1,8 @@ ################# # ENVIRONMENTAL # ################# -PPP_HTTP_PROXY= -PPP_HTTPS_PROXY= +HTTP_PROXY= +HTTPS_PROXY= VERIFY_SSL= ############## diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b71f550..6c50841 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,4 +35,5 @@ jobs: TWILIO_API_SID: dummy TWILIO_API_SECRET: dummy URLSCAN_API_KEY: dummy + PYTHONPATH: . run: poetry run pytest --ignore=dev_env \ No newline at end of file diff --git a/README.md b/README.md index ba69440..f35d05b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ppp_connectors +# APIary A clean, modular set of Python connectors and utilities for working with both **APIs** and **DBMS backends**, unified by a centralized `Broker` abstraction and a consistent interface. Designed for easy testing, code reuse, and plug-and-play extensibility. @@ -76,7 +76,7 @@ Each API connector has both a sync and async version (e.g., `URLScanConnector` a ### 🌐 Sync Example (URLScan) ``` python -from ppp_connectors.api_connectors.urlscan import URLScanConnector +from apiary.api_connectors.urlscan import URLScanConnector scanner = URLScanConnector(load_env_vars=True) result = scanner.scan(url="https://example.com") @@ -87,7 +87,7 @@ print(result.json()) ### ⚡ Async Example (URLScan) ``` python import asyncio -from ppp_connectors.api_connectors.urlscan import AsyncURLScanConnector +from apiary.api_connectors.urlscan import AsyncURLScanConnector async def main(): scanner = AsyncURLScanConnector(load_env_vars=True) @@ -135,7 +135,7 @@ API connectors inherit from the `Broker` class and support flexible proxy config *Using a single proxy:* ```python -from ppp_connectors.api_connectors.urlscan import URLScanConnector +from apiary.api_connectors.urlscan import URLScanConnector conn = URLScanConnector(proxy="http://myproxy:8080") ``` @@ -196,7 +196,7 @@ Note: `query(...)` is deprecated in favor of `find(filter=..., projection=..., b Sync connector ```python -from ppp_connectors.dbms_connectors.mongo import MongoConnector +from apiary.dbms_connectors.mongo import MongoConnector # Recommended: use as a context manager (auto-closes) with MongoConnector( @@ -237,7 +237,7 @@ finally: Async connector ```python import asyncio -from ppp_connectors.dbms_connectors.mongo_async import AsyncMongoConnector +from apiary.dbms_connectors.mongo_async import AsyncMongoConnector async def main(): async with AsyncMongoConnector( @@ -266,7 +266,7 @@ asyncio.run(main()) ```python # The query method returns a generator; use list() or iterate to access results -from ppp_connectors.dbms_connectors.elasticsearch import ElasticsearchConnector +from apiary.dbms_connectors.elasticsearch import ElasticsearchConnector conn = ElasticsearchConnector(["http://localhost:9200"]) results = list(conn.query("my-index", {"query": {"match_all": {}}})) @@ -279,7 +279,7 @@ for doc in results: For automatic connection handling, use `ODBCConnector` as a context manager ```python -from ppp_connectors.dbms_connectors.odbc import ODBCConnector +from apiary.dbms_connectors.odbc import ODBCConnector with ODBCConnector("DSN=PostgresLocal;UID=postgres;PWD=postgres") as db: rows = conn.query("SELECT * FROM my_table") @@ -289,7 +289,7 @@ with ODBCConnector("DSN=PostgresLocal;UID=postgres;PWD=postgres") as db: If you'd like to keep manual control, you can still use the `.close()` method ```python -from ppp_connectors.dbms_connectors.odbc import ODBCConnector +from apiary.dbms_connectors.odbc import ODBCConnector conn = ODBCConnector("DSN=PostgresLocal;UID=postgres;PWD=postgres") rows = conn.query("SELECT * FROM my_table") @@ -300,7 +300,7 @@ conn.close() ### Splunk ```python -from ppp_connectors.dbms_connectors.splunk import SplunkConnector +from apiary.dbms_connectors.splunk import SplunkConnector conn = SplunkConnector("localhost", 8089, "admin", "admin123", scheme="https", verify=False) results = conn.query("search index=_internal | head 5") @@ -344,8 +344,8 @@ markers = To add a new connector: 1. **Module**: Place your module in: - - `ppp_connectors/api_connectors/` for API-based integrations - - `ppp_connectors/dbms_connectors/` for database-style connectors + - `src/apiary/api_connectors/` for API-based integrations + - `src/apiary/dbms_connectors/` for database-style connectors 2. **Base class**: - Use the `Broker` class for APIs @@ -371,8 +371,8 @@ To add a new connector: ## 🛠️ Dev Environment ```bash -git clone https://github.com/FineYoungCannibals/ppp_connectors.git -cd ppp_connectors +git clone https://github.com/robd518/apiary.git +cd apiary cp .env.example .env diff --git a/dev_env/api/test_async_generic.py b/dev_env/api/test_async_generic.py new file mode 100644 index 0000000..db3951f --- /dev/null +++ b/dev_env/api/test_async_generic.py @@ -0,0 +1,57 @@ +import asyncio +from typing import Any, Dict, Iterable, Tuple + +from apiary.api_connectors.generic import AsyncGenericConnector + +# Give AsyncGenericConnector lightweight context-manager support without +# modifying the library source. +if not hasattr(AsyncGenericConnector, "__aenter__"): + async def _async_enter(self: AsyncGenericConnector) -> AsyncGenericConnector: + return self + + async def _async_exit( + self: AsyncGenericConnector, + exc_type, + exc, + tb, + ) -> None: + await self.session.aclose() + + AsyncGenericConnector.__aenter__ = _async_enter # type: ignore[attr-defined] + AsyncGenericConnector.__aexit__ = _async_exit # type: ignore[attr-defined] + +RequestSpec = Tuple[str, str, Dict[str, Any]] + +REQUESTS: Iterable[RequestSpec] = ( + ("GET", "/get", {"params": {"label": "alpha"}}), + ("GET", "/delay/1", {"params": {"label": "beta"}}), + ("GET", "/uuid", {"headers": {"X-Demo": "gamma"}}), +) + + +async def fetch(connector: AsyncGenericConnector, method: str, endpoint: str, **kwargs) -> Dict[str, Any]: + response = await connector.request(method, endpoint, **kwargs) + return { + "endpoint": endpoint, + "status": response.status_code, + "json": response.json(), + } + + +async def main() -> None: + async with AsyncGenericConnector( + base_url="http://httpbin.org", + enable_logging=False, + timeout=15, + ) as connector: + tasks = [fetch(connector, method, endpoint, **req_kwargs) for method, endpoint, req_kwargs in REQUESTS] + results = await asyncio.gather(*tasks) + + print("Completed concurrent requests:") + for result in results: + print(f"- {result['endpoint']} -> {result['status']}") + print(f" payload: {result['json']}") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/dev_env/api/test_flashpoint.py b/dev_env/api/test_flashpoint.py index 32d63ed..c44a958 100644 --- a/dev_env/api/test_flashpoint.py +++ b/dev_env/api/test_flashpoint.py @@ -1,4 +1,4 @@ -from ppp_connectors.api_connectors.flashpoint import FlashpointConnector +from apiary.api_connectors.flashpoint import FlashpointConnector import httpx fp = FlashpointConnector( diff --git a/dev_env/api/test_ipqs.py b/dev_env/api/test_ipqs.py new file mode 100644 index 0000000..dfac88a --- /dev/null +++ b/dev_env/api/test_ipqs.py @@ -0,0 +1,28 @@ +from apiary.api_connectors.ipqs import AsyncIPQSConnector, IPQSConnector +import asyncio +from apiary.helpers import combine_env_configs, setup_logger +from typing import Dict, Any +import json + + +env_config: Dict[str, Any] = combine_env_configs() + +async def main(): + ipqs = AsyncIPQSConnector( + api_key=env_config["IPQS_API_KEY"], + enable_logging=True, + load_env_vars=True, + trust_env=True, + verify=False + ) + + res = await ipqs.malicious_url( + query="cracked.to" + ) + + print(res) + print(res.json()) + print(res.headers) + +asyncio.run(main()) +# main() \ No newline at end of file diff --git a/dev_env/api/test_urlscan.py b/dev_env/api/test_urlscan.py index 16eca5b..35ee462 100644 --- a/dev_env/api/test_urlscan.py +++ b/dev_env/api/test_urlscan.py @@ -1,4 +1,4 @@ -from ppp_connectors.api_connectors.urlscan import URLScanConnector, AsyncURLScanConnector +from apiary.api_connectors.urlscan import URLScanConnector, AsyncURLScanConnector urlscan = URLScanConnector( load_env_vars=True, diff --git a/dev_env/elasticsearch/test_es.py b/dev_env/elasticsearch/test_es.py index 2b38390..2854300 100644 --- a/dev_env/elasticsearch/test_es.py +++ b/dev_env/elasticsearch/test_es.py @@ -1,5 +1,5 @@ -from ppp_connectors.dbms_connectors.elasticsearch import ElasticsearchConnector -from ppp_connectors.helpers import combine_env_configs, setup_logger +from apiary.dbms_connectors.elasticsearch import ElasticsearchConnector +from apiary.helpers import combine_env_configs, setup_logger from typing import Dict, Any import json diff --git a/dev_env/example.py b/dev_env/example.py index fbd1f51..e7df5df 100644 --- a/dev_env/example.py +++ b/dev_env/example.py @@ -1,5 +1,5 @@ -from ppp_connectors.dbms_connectors.mongo import MongoConnector -from ppp_connectors.helpers import combine_env_configs +from apiary.dbms_connectors.mongo import MongoConnector +from apiary.helpers import combine_env_configs from typing import Dict, Any env_config: Dict[str, Any] = combine_env_configs() diff --git a/dev_env/mongo/test_mongo.py b/dev_env/mongo/test_mongo.py index cdbaa81..9e6a13f 100644 --- a/dev_env/mongo/test_mongo.py +++ b/dev_env/mongo/test_mongo.py @@ -1,6 +1,6 @@ from typing import Dict, Any, List -from ppp_connectors.dbms_connectors.mongo import MongoConnector -from ppp_connectors.helpers import combine_env_configs, setup_logger +from apiary.dbms_connectors.mongo import MongoConnector +from apiary.helpers import combine_env_configs, setup_logger def main() -> None: diff --git a/dev_env/mongo/test_mongo_async.py b/dev_env/mongo/test_mongo_async.py index bcf853d..80c18c4 100644 --- a/dev_env/mongo/test_mongo_async.py +++ b/dev_env/mongo/test_mongo_async.py @@ -1,8 +1,8 @@ import asyncio from typing import Any, Dict, List -from ppp_connectors.dbms_connectors.mongo_async import AsyncMongoConnector -from ppp_connectors.helpers import combine_env_configs, setup_logger +from apiary.dbms_connectors.mongo_async import AsyncMongoConnector +from apiary.helpers import combine_env_configs, setup_logger async def main() -> None: diff --git a/dev_env/odbc/test_odbc.py b/dev_env/odbc/test_odbc.py index f89e2cb..7bf4589 100644 --- a/dev_env/odbc/test_odbc.py +++ b/dev_env/odbc/test_odbc.py @@ -1,5 +1,5 @@ -from ppp_connectors.dbms_connectors.odbc import ODBCConnector -from ppp_connectors.helpers import combine_env_configs, setup_logger +from apiary.dbms_connectors.odbc import ODBCConnector +from apiary.helpers import combine_env_configs, setup_logger from typing import Dict, Any env_config: Dict[str, Any] = combine_env_configs() diff --git a/dev_env/splunk/test_splunk.py b/dev_env/splunk/test_splunk.py index 8d888df..84c8916 100644 --- a/dev_env/splunk/test_splunk.py +++ b/dev_env/splunk/test_splunk.py @@ -1,5 +1,5 @@ -from ppp_connectors.dbms_connectors.splunk import SplunkConnector -from ppp_connectors.helpers import combine_env_configs, setup_logger +from apiary.dbms_connectors.splunk import SplunkConnector +from apiary.helpers import combine_env_configs, setup_logger from typing import Dict, Any env_config: Dict[str, Any] = combine_env_configs() diff --git a/poetry.lock b/poetry.lock index dbb99cb..3326af1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -679,7 +679,7 @@ zstd = ["zstandard"] name = "pyodbc" version = "5.3.0" description = "DB API module for ODBC" -optional = true +optional = false python-versions = ">=3.9" groups = ["main"] markers = "extra == \"odbc\"" @@ -1378,4 +1378,4 @@ odbc = ["pyodbc"] [metadata] lock-version = "2.1" python-versions = "^3.10" -content-hash = "0d4e179b4e600b3f627bfe0514b4147ee3f17b5aaaf2b7fb374fe4befe25abba" +content-hash = "7c335bd1bffc7815b9c7e4c7c8869fb9dc389befdd7c3ab841eea8ffe799284d" diff --git a/ppp_connectors/__init__.py b/ppp_connectors/__init__.py deleted file mode 100644 index 5872ab9..0000000 --- a/ppp_connectors/__init__.py +++ /dev/null @@ -1,43 +0,0 @@ -# API connectors -import warnings - -warnings.warn( - ( - "The 'ppp_connectors' package is deprecated and no longer maintained. " - "Please migrate to the 'apiary' package. " - "See https://github.com/robd518/apiary for details." - ), - DeprecationWarning, - stacklevel=2, -) - -from ppp_connectors.api_connectors import ( - urlscan, - spycloud, - twilio, - flashpoint, - ipqs, - generic, -) - -# DBMS connectors -from ppp_connectors.dbms_connectors import ( - elasticsearch, - mongo, - odbc, - splunk -) - -# Export the modules and re-exports -__all__ = [ - "elasticsearch", - "flashpoint", - "generic", - "ipqs", - "mongo", - "odbc", - "splunk", - "spycloud", - "twilio", - "urlscan", -] \ No newline at end of file diff --git a/ppp_connectors/broker.py b/ppp_connectors/broker.py deleted file mode 100644 index 896dad4..0000000 --- a/ppp_connectors/broker.py +++ /dev/null @@ -1,14 +0,0 @@ -""" -Shim for backward compatibility. -Forwards to ppp_connectors.connectors.broker. -TODO: Deprecate this file in a future major release. -""" - -import warnings -from ppp_connectors.connectors.broker import * - -warnings.warn( - "ppp_connectors.broker is deprecated and will be removed in a future release; use ppp_connectors.connectors.broker instead.", - DeprecationWarning, - stacklevel=2 -) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index f024178..e4dd835 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,12 @@ [tool.poetry] -name = "ppp-connectors" -packages = [{ include = "ppp_connectors" }] -version = "1.1.13" +name = "apiary" +packages = [{ include = "apiary", from = "src" }] +version = "2.0.0" description = "A simple, lightweight set of connectors and functions to various APIs and DBMSs, controlled by a central broker." authors = ["Rob D'Aveta "] readme = "README.md" +homepage = "https://github.com/robd518/apiary" +repository = "https://github.com/robd518/apiary" [tool.poetry.dependencies] python = "^3.10" @@ -12,9 +14,9 @@ python-dotenv = "^1.1.1" pymongo = "^4.15.0" elasticsearch = "^9.1.1" splunk-sdk = "^2.1.1" -pyodbc = { version = "^5.2.0", optional = true } httpx = "^0.28.1" tenacity = "^9.1.2" +pyodbc = "^5.3.0" [tool.poetry.extras] odbc = ["pyodbc"] diff --git a/src/apiary/__init__.py b/src/apiary/__init__.py new file mode 100644 index 0000000..f0e1e27 --- /dev/null +++ b/src/apiary/__init__.py @@ -0,0 +1,31 @@ +# API connectors +from apiary.api_connectors import ( + urlscan, + spycloud, + twilio, + flashpoint, + ipqs, + generic, +) + +# DBMS connectors +from apiary.dbms_connectors import ( + elasticsearch, + mongo, + odbc, + splunk +) + +# Export the modules and re-exports +__all__ = [ + "elasticsearch", + "flashpoint", + "generic", + "ipqs", + "mongo", + "odbc", + "splunk", + "spycloud", + "twilio", + "urlscan", +] \ No newline at end of file diff --git a/ppp_connectors/api_connectors/__init__.py b/src/apiary/api_connectors/__init__.py similarity index 100% rename from ppp_connectors/api_connectors/__init__.py rename to src/apiary/api_connectors/__init__.py diff --git a/ppp_connectors/api_connectors/broker.py b/src/apiary/api_connectors/broker.py similarity index 98% rename from ppp_connectors/api_connectors/broker.py rename to src/apiary/api_connectors/broker.py index 571f87f..ea41a56 100644 --- a/ppp_connectors/api_connectors/broker.py +++ b/src/apiary/api_connectors/broker.py @@ -2,7 +2,7 @@ from httpx import Auth from typing import Optional, Dict, Any, Union, Iterable, Callable, ParamSpec, TypeVar, Type from tenacity import retry, stop_after_attempt, wait_exponential, RetryError, retry_if_exception, AsyncRetrying -from ppp_connectors.helpers import setup_logger, combine_env_configs +from apiary.helpers import setup_logger, combine_env_configs from functools import wraps import inspect import os @@ -31,7 +31,7 @@ def bubble_broker_init_signature(*, exclude: Iterable[str] = ("base_url",)): parameters from Broker.__init__ for better IDE/tab-completion hints. Usage: - from ppp_connectors.api_connectors.broker import Broker, bubble_broker_init_signature + from apiary.api_connectors.broker import Broker, bubble_broker_init_signature @bubble_broker_init_signature() class MyConnector(Broker): diff --git a/ppp_connectors/api_connectors/flashpoint.py b/src/apiary/api_connectors/flashpoint.py similarity index 98% rename from ppp_connectors/api_connectors/flashpoint.py rename to src/apiary/api_connectors/flashpoint.py index 40b1bd1..b296b79 100644 --- a/ppp_connectors/api_connectors/flashpoint.py +++ b/src/apiary/api_connectors/flashpoint.py @@ -1,6 +1,6 @@ import httpx from typing import Optional -from ppp_connectors.api_connectors.broker import Broker, AsyncBroker, bubble_broker_init_signature, log_method_call +from apiary.api_connectors.broker import Broker, AsyncBroker, bubble_broker_init_signature, log_method_call @bubble_broker_init_signature() class FlashpointConnector(Broker): diff --git a/ppp_connectors/api_connectors/generic.py b/src/apiary/api_connectors/generic.py similarity index 96% rename from ppp_connectors/api_connectors/generic.py rename to src/apiary/api_connectors/generic.py index 094fb15..a1e904d 100644 --- a/ppp_connectors/api_connectors/generic.py +++ b/src/apiary/api_connectors/generic.py @@ -1,6 +1,6 @@ import httpx from typing import Dict, Any, Optional -from ppp_connectors.api_connectors.broker import Broker, AsyncBroker, bubble_broker_init_signature, log_method_call +from apiary.api_connectors.broker import Broker, AsyncBroker, bubble_broker_init_signature, log_method_call @bubble_broker_init_signature() class GenericConnector(Broker): diff --git a/ppp_connectors/api_connectors/ipqs.py b/src/apiary/api_connectors/ipqs.py similarity index 95% rename from ppp_connectors/api_connectors/ipqs.py rename to src/apiary/api_connectors/ipqs.py index e627732..0d3c324 100644 --- a/ppp_connectors/api_connectors/ipqs.py +++ b/src/apiary/api_connectors/ipqs.py @@ -1,7 +1,7 @@ import httpx from typing import Optional from urllib.parse import quote -from ppp_connectors.api_connectors.broker import Broker, AsyncBroker, bubble_broker_init_signature, log_method_call +from apiary.api_connectors.broker import Broker, AsyncBroker, bubble_broker_init_signature, log_method_call @bubble_broker_init_signature() class IPQSConnector(Broker): diff --git a/ppp_connectors/api_connectors/spycloud.py b/src/apiary/api_connectors/spycloud.py similarity index 98% rename from ppp_connectors/api_connectors/spycloud.py rename to src/apiary/api_connectors/spycloud.py index cfd40a7..e1d2e88 100644 --- a/ppp_connectors/api_connectors/spycloud.py +++ b/src/apiary/api_connectors/spycloud.py @@ -1,6 +1,6 @@ import httpx from typing import Dict, Any, Optional -from ppp_connectors.api_connectors.broker import AsyncBroker, Broker, bubble_broker_init_signature, log_method_call +from apiary.api_connectors.broker import AsyncBroker, Broker, bubble_broker_init_signature, log_method_call @bubble_broker_init_signature() diff --git a/ppp_connectors/api_connectors/twilio.py b/src/apiary/api_connectors/twilio.py similarity index 95% rename from ppp_connectors/api_connectors/twilio.py rename to src/apiary/api_connectors/twilio.py index 9e03160..b41b586 100644 --- a/ppp_connectors/api_connectors/twilio.py +++ b/src/apiary/api_connectors/twilio.py @@ -1,8 +1,8 @@ from datetime import date, datetime from typing import Dict, Any, List, Set, Union, Optional from httpx import BasicAuth, Response -from ppp_connectors.api_connectors.broker import AsyncBroker, Broker, bubble_broker_init_signature, log_method_call -from ppp_connectors.helpers import validate_date_string +from apiary.api_connectors.broker import AsyncBroker, Broker, bubble_broker_init_signature, log_method_call +from apiary.helpers import validate_date_string @bubble_broker_init_signature() class TwilioConnector(Broker): diff --git a/ppp_connectors/api_connectors/urlscan.py b/src/apiary/api_connectors/urlscan.py similarity index 97% rename from ppp_connectors/api_connectors/urlscan.py rename to src/apiary/api_connectors/urlscan.py index f68e181..672565e 100644 --- a/ppp_connectors/api_connectors/urlscan.py +++ b/src/apiary/api_connectors/urlscan.py @@ -1,6 +1,6 @@ import httpx from typing import Dict, Any, Optional -from ppp_connectors.api_connectors.broker import AsyncBroker, Broker, bubble_broker_init_signature, log_method_call +from apiary.api_connectors.broker import AsyncBroker, Broker, bubble_broker_init_signature, log_method_call @bubble_broker_init_signature() class URLScanConnector(Broker): diff --git a/ppp_connectors/dbms_connectors/__init__.py b/src/apiary/dbms_connectors/__init__.py similarity index 100% rename from ppp_connectors/dbms_connectors/__init__.py rename to src/apiary/dbms_connectors/__init__.py diff --git a/ppp_connectors/dbms_connectors/elasticsearch.py b/src/apiary/dbms_connectors/elasticsearch.py similarity index 99% rename from ppp_connectors/dbms_connectors/elasticsearch.py rename to src/apiary/dbms_connectors/elasticsearch.py index 67e2049..3abdf12 100644 --- a/ppp_connectors/dbms_connectors/elasticsearch.py +++ b/src/apiary/dbms_connectors/elasticsearch.py @@ -3,7 +3,7 @@ try: - from ppp_connectors.helpers import setup_logger + from apiary.helpers import setup_logger _default_logger = setup_logger(name="elasticsearch") except ImportError: import logging diff --git a/ppp_connectors/dbms_connectors/mongo.py b/src/apiary/dbms_connectors/mongo.py similarity index 99% rename from ppp_connectors/dbms_connectors/mongo.py rename to src/apiary/dbms_connectors/mongo.py index 83f6e8a..8af2e86 100644 --- a/ppp_connectors/dbms_connectors/mongo.py +++ b/src/apiary/dbms_connectors/mongo.py @@ -8,7 +8,7 @@ from tenacity import Retrying, stop_after_attempt, wait_fixed, retry_if_exception_type from typing import List, Dict, Any, Optional, Generator, Type, Union from types import TracebackType -from ppp_connectors.helpers import setup_logger +from apiary.helpers import setup_logger _DEFAULT_LOGGER = object() diff --git a/ppp_connectors/dbms_connectors/mongo_async.py b/src/apiary/dbms_connectors/mongo_async.py similarity index 99% rename from ppp_connectors/dbms_connectors/mongo_async.py rename to src/apiary/dbms_connectors/mongo_async.py index 5e7550a..ff9240c 100644 --- a/ppp_connectors/dbms_connectors/mongo_async.py +++ b/src/apiary/dbms_connectors/mongo_async.py @@ -10,7 +10,7 @@ ConnectionFailure, ) from tenacity import AsyncRetrying, stop_after_attempt, wait_fixed, retry_if_exception_type -from ppp_connectors.helpers import setup_logger +from apiary.helpers import setup_logger _DEFAULT_LOGGER = object() diff --git a/ppp_connectors/dbms_connectors/odbc.py b/src/apiary/dbms_connectors/odbc.py similarity index 95% rename from ppp_connectors/dbms_connectors/odbc.py rename to src/apiary/dbms_connectors/odbc.py index 8b5e157..ac5519c 100644 --- a/ppp_connectors/dbms_connectors/odbc.py +++ b/src/apiary/dbms_connectors/odbc.py @@ -1,6 +1,6 @@ from importlib import import_module from typing import Any, Dict, Generator, List -from ppp_connectors.helpers import setup_logger +from apiary.helpers import setup_logger _PYODBC_MODULE = None @@ -15,7 +15,7 @@ def _get_pyodbc(): _PYODBC_MODULE = import_module("pyodbc") except ImportError as exc: raise ImportError( - "pyodbc is not installed. Install ppp_connectors[odbc] or add pyodbc to your deps." + "pyodbc is not installed. Install apiary[odbc] or add pyodbc to your deps." ) from exc return _PYODBC_MODULE diff --git a/ppp_connectors/dbms_connectors/splunk.py b/src/apiary/dbms_connectors/splunk.py similarity index 98% rename from ppp_connectors/dbms_connectors/splunk.py rename to src/apiary/dbms_connectors/splunk.py index 78390a7..efd05b7 100644 --- a/ppp_connectors/dbms_connectors/splunk.py +++ b/src/apiary/dbms_connectors/splunk.py @@ -1,6 +1,6 @@ import httpx from typing import Generator, Dict, Any, Optional -from ppp_connectors.helpers import setup_logger +from apiary.helpers import setup_logger class SplunkConnector: diff --git a/ppp_connectors/helpers.py b/src/apiary/helpers.py similarity index 100% rename from ppp_connectors/helpers.py rename to src/apiary/helpers.py diff --git a/ppp_connectors/tests/__init__.py b/src/apiary/tests/__init__.py similarity index 100% rename from ppp_connectors/tests/__init__.py rename to src/apiary/tests/__init__.py diff --git a/ppp_connectors/tests/conftest.py b/src/apiary/tests/conftest.py similarity index 100% rename from ppp_connectors/tests/conftest.py rename to src/apiary/tests/conftest.py diff --git a/ppp_connectors/tests/test_broker/test_integration_broker.py b/src/apiary/tests/test_broker/test_integration_broker.py similarity index 89% rename from ppp_connectors/tests/test_broker/test_integration_broker.py rename to src/apiary/tests/test_broker/test_integration_broker.py index 838ba8f..2cfda86 100644 --- a/ppp_connectors/tests/test_broker/test_integration_broker.py +++ b/src/apiary/tests/test_broker/test_integration_broker.py @@ -1,5 +1,5 @@ import httpx -from ppp_connectors.api_connectors.broker import Broker +from apiary.api_connectors.broker import Broker def test_integration_get_with_mock_transport(): def handler(request): diff --git a/ppp_connectors/tests/test_broker/test_unit_asyncbroker.py b/src/apiary/tests/test_broker/test_unit_asyncbroker.py similarity index 91% rename from ppp_connectors/tests/test_broker/test_unit_asyncbroker.py rename to src/apiary/tests/test_broker/test_unit_asyncbroker.py index ab1c6e5..924fb19 100644 --- a/ppp_connectors/tests/test_broker/test_unit_asyncbroker.py +++ b/src/apiary/tests/test_broker/test_unit_asyncbroker.py @@ -1,6 +1,6 @@ import pytest import httpx -from ppp_connectors.api_connectors.broker import AsyncBroker +from apiary.api_connectors.broker import AsyncBroker def test_asyncbroker_rejects_mounts(): diff --git a/ppp_connectors/tests/test_broker/test_unit_broker.py b/src/apiary/tests/test_broker/test_unit_broker.py similarity index 92% rename from ppp_connectors/tests/test_broker/test_unit_broker.py rename to src/apiary/tests/test_broker/test_unit_broker.py index ba0887d..b960e6a 100644 --- a/ppp_connectors/tests/test_broker/test_unit_broker.py +++ b/src/apiary/tests/test_broker/test_unit_broker.py @@ -1,5 +1,5 @@ import pytest -from ppp_connectors.api_connectors.broker import Broker +from apiary.api_connectors.broker import Broker def test_get_calls_make_request(mocker): broker = Broker(base_url="https://example.com") @@ -15,7 +15,7 @@ def test_post_calls_make_request(mocker): def test_logging_enabled_logs_message(mocker): mock_logger = mocker.MagicMock() - mock_setup_logger = mocker.patch("ppp_connectors.api_connectors.broker.setup_logger", return_value=mock_logger) + mock_setup_logger = mocker.patch("apiary.api_connectors.broker.setup_logger", return_value=mock_logger) broker = Broker(base_url="https://example.com", enable_logging=True) broker._log("test message") mock_logger.info.assert_called_once_with("test message") @@ -23,7 +23,7 @@ def test_logging_enabled_logs_message(mocker): def test_env_only_proxy_from_dotenv(monkeypatch, mocker): # Simulate .env via env_config when load_env_vars=True mock_combine = mocker.patch( - "ppp_connectors.api_connectors.broker.combine_env_configs", + "apiary.api_connectors.broker.combine_env_configs", return_value={"HTTPS_PROXY": "http://env-proxy:8080"} ) broker = Broker(base_url="https://example.com", load_env_vars=True, trust_env=False) diff --git a/ppp_connectors/tests/test_elasticsearch/test_unit_elasticsearch.py b/src/apiary/tests/test_elasticsearch/test_unit_elasticsearch.py similarity index 86% rename from ppp_connectors/tests/test_elasticsearch/test_unit_elasticsearch.py rename to src/apiary/tests/test_elasticsearch/test_unit_elasticsearch.py index 1ee0b07..a081d1e 100644 --- a/ppp_connectors/tests/test_elasticsearch/test_unit_elasticsearch.py +++ b/src/apiary/tests/test_elasticsearch/test_unit_elasticsearch.py @@ -1,6 +1,6 @@ import unittest from unittest.mock import patch, MagicMock -from ppp_connectors.dbms_connectors.elasticsearch import ElasticsearchConnector +from apiary.dbms_connectors.elasticsearch import ElasticsearchConnector class TestElasticsearchConnector(unittest.TestCase): @@ -13,7 +13,7 @@ def setUp(self): logger=self.mock_logger ) - @patch("ppp_connectors.dbms_connectors.elasticsearch.Elasticsearch") + @patch("apiary.dbms_connectors.elasticsearch.Elasticsearch") def test_initialization(self, mock_es): ElasticsearchConnector( hosts=["http://localhost:9200"], @@ -23,7 +23,7 @@ def test_initialization(self, mock_es): ) mock_es.assert_called_with(["http://localhost:9200"], basic_auth=("user", "pass")) - @patch("ppp_connectors.dbms_connectors.elasticsearch.Elasticsearch") + @patch("apiary.dbms_connectors.elasticsearch.Elasticsearch") def test_query_scroll(self, mock_es): mock_client = MagicMock() mock_client.search.return_value = { @@ -45,7 +45,7 @@ def test_query_scroll(self, mock_es): self.assertEqual(len(results), 3) self.assertEqual(results[0]["_id"], 1) - @patch("ppp_connectors.dbms_connectors.elasticsearch.helpers.bulk") + @patch("apiary.dbms_connectors.elasticsearch.helpers.bulk") def test_bulk_insert(self, mock_bulk): mock_bulk.return_value = (3, []) data = [{"_id": "1", "name": "Alice"}, {"_id": "2", "name": "Bob"}, {"_id": "3", "name": "Charlie"}] @@ -54,7 +54,7 @@ def test_bulk_insert(self, mock_bulk): self.assertEqual(errors, []) self.mock_logger.info.assert_called_with("Bulk insert completed successfully") - @patch("ppp_connectors.dbms_connectors.elasticsearch.helpers.bulk") + @patch("apiary.dbms_connectors.elasticsearch.helpers.bulk") def test_bulk_insert_with_errors(self, mock_bulk): mock_bulk.return_value = (2, [{"error": "failed to insert"}]) data = [{"_id": "1", "name": "Alice"}, {"_id": "2", "name": "Bob"}] diff --git a/ppp_connectors/tests/test_flashpoint/cassettes/test_flashpoint_search_fraud_vcr.yaml b/src/apiary/tests/test_flashpoint/cassettes/test_flashpoint_search_fraud_vcr.yaml similarity index 100% rename from ppp_connectors/tests/test_flashpoint/cassettes/test_flashpoint_search_fraud_vcr.yaml rename to src/apiary/tests/test_flashpoint/cassettes/test_flashpoint_search_fraud_vcr.yaml diff --git a/ppp_connectors/tests/test_flashpoint/test_integration_flashpoint.py b/src/apiary/tests/test_flashpoint/test_integration_flashpoint.py similarity index 83% rename from ppp_connectors/tests/test_flashpoint/test_integration_flashpoint.py rename to src/apiary/tests/test_flashpoint/test_integration_flashpoint.py index d2b0cc6..670faeb 100644 --- a/ppp_connectors/tests/test_flashpoint/test_integration_flashpoint.py +++ b/src/apiary/tests/test_flashpoint/test_integration_flashpoint.py @@ -1,6 +1,6 @@ import httpx import pytest -from ppp_connectors.api_connectors.flashpoint import FlashpointConnector +from apiary.api_connectors.flashpoint import FlashpointConnector @pytest.mark.integration def test_flashpoint_search_fraud_vcr(vcr_cassette): diff --git a/ppp_connectors/tests/test_flashpoint/test_unit_async_flashpoint.py b/src/apiary/tests/test_flashpoint/test_unit_async_flashpoint.py similarity index 89% rename from ppp_connectors/tests/test_flashpoint/test_unit_async_flashpoint.py rename to src/apiary/tests/test_flashpoint/test_unit_async_flashpoint.py index b7182ed..18770c0 100644 --- a/ppp_connectors/tests/test_flashpoint/test_unit_async_flashpoint.py +++ b/src/apiary/tests/test_flashpoint/test_unit_async_flashpoint.py @@ -1,7 +1,7 @@ import pytest import httpx from unittest.mock import patch, AsyncMock -from ppp_connectors.api_connectors.flashpoint import AsyncFlashpointConnector +from apiary.api_connectors.flashpoint import AsyncFlashpointConnector @pytest.mark.asyncio @@ -26,7 +26,7 @@ async def test_async_init_missing_key(): AsyncFlashpointConnector() -@patch("ppp_connectors.api_connectors.flashpoint.AsyncFlashpointConnector.post", new_callable=AsyncMock) +@patch("apiary.api_connectors.flashpoint.AsyncFlashpointConnector.post", new_callable=AsyncMock) @pytest.mark.asyncio async def test_async_search_fraud(mock_post): import json diff --git a/ppp_connectors/tests/test_flashpoint/test_unit_flashpoint.py b/src/apiary/tests/test_flashpoint/test_unit_flashpoint.py similarity index 90% rename from ppp_connectors/tests/test_flashpoint/test_unit_flashpoint.py rename to src/apiary/tests/test_flashpoint/test_unit_flashpoint.py index f2a2501..3ec9191 100644 --- a/ppp_connectors/tests/test_flashpoint/test_unit_flashpoint.py +++ b/src/apiary/tests/test_flashpoint/test_unit_flashpoint.py @@ -1,7 +1,7 @@ import httpx import pytest from unittest.mock import patch, MagicMock -from ppp_connectors.api_connectors.flashpoint import FlashpointConnector +from apiary.api_connectors.flashpoint import FlashpointConnector def test_init_with_api_key(): connector = FlashpointConnector(api_key="test_token") @@ -22,7 +22,7 @@ def test_init_missing_key(): FlashpointConnector() -@patch("ppp_connectors.api_connectors.flashpoint.FlashpointConnector.post") +@patch("apiary.api_connectors.flashpoint.FlashpointConnector.post") def test_search_fraud(mock_post): import json diff --git a/ppp_connectors/tests/test_generic/cassettes/test_generic_get_github_api.yaml b/src/apiary/tests/test_generic/cassettes/test_generic_get_github_api.yaml similarity index 100% rename from ppp_connectors/tests/test_generic/cassettes/test_generic_get_github_api.yaml rename to src/apiary/tests/test_generic/cassettes/test_generic_get_github_api.yaml diff --git a/ppp_connectors/tests/test_generic/test_integration_generic_connector.py b/src/apiary/tests/test_generic/test_integration_generic_connector.py similarity index 83% rename from ppp_connectors/tests/test_generic/test_integration_generic_connector.py rename to src/apiary/tests/test_generic/test_integration_generic_connector.py index c473169..3509569 100644 --- a/ppp_connectors/tests/test_generic/test_integration_generic_connector.py +++ b/src/apiary/tests/test_generic/test_integration_generic_connector.py @@ -1,6 +1,6 @@ import pytest import vcr -from ppp_connectors.api_connectors.generic import GenericConnector +from apiary.api_connectors.generic import GenericConnector @pytest.mark.integration def test_generic_get_github_api(vcr_cassette): diff --git a/ppp_connectors/tests/test_generic/test_unit_async_generic_connector.py b/src/apiary/tests/test_generic/test_unit_async_generic_connector.py similarity index 84% rename from ppp_connectors/tests/test_generic/test_unit_async_generic_connector.py rename to src/apiary/tests/test_generic/test_unit_async_generic_connector.py index 80410e5..f916c96 100644 --- a/ppp_connectors/tests/test_generic/test_unit_async_generic_connector.py +++ b/src/apiary/tests/test_generic/test_unit_async_generic_connector.py @@ -1,7 +1,7 @@ import pytest import httpx from unittest.mock import AsyncMock, patch -from ppp_connectors.api_connectors.generic import AsyncGenericConnector +from apiary.api_connectors.generic import AsyncGenericConnector @pytest.mark.asyncio @@ -10,7 +10,7 @@ async def test_async_init_sets_base_url(): assert connector.base_url == "https://example.com" -@patch("ppp_connectors.api_connectors.generic.AsyncGenericConnector._make_request", new_callable=AsyncMock) +@patch("apiary.api_connectors.generic.AsyncGenericConnector._make_request", new_callable=AsyncMock) @pytest.mark.asyncio async def test_async_get_request(mock_make_request): mock_response = httpx.Response(200, json={"result": "ok"}) @@ -32,7 +32,7 @@ async def test_async_get_request(mock_make_request): ) -@patch("ppp_connectors.api_connectors.generic.AsyncGenericConnector._make_request", new_callable=AsyncMock) +@patch("apiary.api_connectors.generic.AsyncGenericConnector._make_request", new_callable=AsyncMock) @pytest.mark.asyncio async def test_async_post_request(mock_make_request): mock_response = httpx.Response(200, json={"posted": True}) diff --git a/ppp_connectors/tests/test_generic/test_unit_generic_connector.py b/src/apiary/tests/test_generic/test_unit_generic_connector.py similarity index 82% rename from ppp_connectors/tests/test_generic/test_unit_generic_connector.py rename to src/apiary/tests/test_generic/test_unit_generic_connector.py index 299cd9a..0ab2985 100644 --- a/ppp_connectors/tests/test_generic/test_unit_generic_connector.py +++ b/src/apiary/tests/test_generic/test_unit_generic_connector.py @@ -1,6 +1,6 @@ import pytest from unittest.mock import patch, MagicMock -from ppp_connectors.api_connectors.generic import GenericConnector +from apiary.api_connectors.generic import GenericConnector def test_init_sets_base_url(): @@ -8,7 +8,7 @@ def test_init_sets_base_url(): assert connector.base_url == "https://example.com" -@patch("ppp_connectors.api_connectors.generic.GenericConnector._make_request") +@patch("apiary.api_connectors.generic.GenericConnector._make_request") def test_get_request(mock_make_request): mock_response = MagicMock() mock_response.json.return_value = {"result": "ok"} @@ -21,7 +21,7 @@ def test_get_request(mock_make_request): mock_make_request.assert_called_once_with("GET", "/test", params=None) -@patch("ppp_connectors.api_connectors.generic.GenericConnector._make_request") +@patch("apiary.api_connectors.generic.GenericConnector._make_request") def test_post_request(mock_make_request): mock_response = MagicMock() mock_response.json.return_value = {"posted": True} diff --git a/ppp_connectors/tests/test_ipqs/__init__.py b/src/apiary/tests/test_ipqs/__init__.py similarity index 100% rename from ppp_connectors/tests/test_ipqs/__init__.py rename to src/apiary/tests/test_ipqs/__init__.py diff --git a/ppp_connectors/tests/test_ipqs/cassettes/test_ipqs_malicious_url_vcr.yaml b/src/apiary/tests/test_ipqs/cassettes/test_ipqs_malicious_url_vcr.yaml similarity index 100% rename from ppp_connectors/tests/test_ipqs/cassettes/test_ipqs_malicious_url_vcr.yaml rename to src/apiary/tests/test_ipqs/cassettes/test_ipqs_malicious_url_vcr.yaml diff --git a/ppp_connectors/tests/test_ipqs/test_integration_ipqs.py b/src/apiary/tests/test_ipqs/test_integration_ipqs.py similarity index 87% rename from ppp_connectors/tests/test_ipqs/test_integration_ipqs.py rename to src/apiary/tests/test_ipqs/test_integration_ipqs.py index 7bd3abd..01eb673 100644 --- a/ppp_connectors/tests/test_ipqs/test_integration_ipqs.py +++ b/src/apiary/tests/test_ipqs/test_integration_ipqs.py @@ -1,6 +1,6 @@ import httpx import pytest -from ppp_connectors.api_connectors.ipqs import IPQSConnector +from apiary.api_connectors.ipqs import IPQSConnector @pytest.mark.integration def test_ipqs_malicious_url_vcr(vcr_cassette): diff --git a/ppp_connectors/tests/test_ipqs/test_unit_async_ipqs.py b/src/apiary/tests/test_ipqs/test_unit_async_ipqs.py similarity index 91% rename from ppp_connectors/tests/test_ipqs/test_unit_async_ipqs.py rename to src/apiary/tests/test_ipqs/test_unit_async_ipqs.py index 2b32e2f..df461d2 100644 --- a/ppp_connectors/tests/test_ipqs/test_unit_async_ipqs.py +++ b/src/apiary/tests/test_ipqs/test_unit_async_ipqs.py @@ -1,7 +1,7 @@ import pytest import httpx from unittest.mock import patch, AsyncMock -from ppp_connectors.api_connectors.ipqs import AsyncIPQSConnector +from apiary.api_connectors.ipqs import AsyncIPQSConnector @pytest.mark.asyncio @@ -26,7 +26,7 @@ async def test_async_init_missing_key(): AsyncIPQSConnector() -@patch("ppp_connectors.api_connectors.ipqs.AsyncIPQSConnector.post", new_callable=AsyncMock) +@patch("apiary.api_connectors.ipqs.AsyncIPQSConnector.post", new_callable=AsyncMock) @pytest.mark.asyncio async def test_async_malicious_url(mock_post): import json diff --git a/ppp_connectors/tests/test_ipqs/test_unit_ipqs.py b/src/apiary/tests/test_ipqs/test_unit_ipqs.py similarity index 91% rename from ppp_connectors/tests/test_ipqs/test_unit_ipqs.py rename to src/apiary/tests/test_ipqs/test_unit_ipqs.py index cda66fc..9bad35c 100644 --- a/ppp_connectors/tests/test_ipqs/test_unit_ipqs.py +++ b/src/apiary/tests/test_ipqs/test_unit_ipqs.py @@ -1,7 +1,7 @@ import httpx import pytest from unittest.mock import patch, MagicMock -from ppp_connectors.api_connectors.ipqs import IPQSConnector +from apiary.api_connectors.ipqs import IPQSConnector def test_init_with_api_key(): @@ -22,7 +22,7 @@ def test_init_missing_key(): IPQSConnector() -@patch("ppp_connectors.api_connectors.ipqs.IPQSConnector.post") +@patch("apiary.api_connectors.ipqs.IPQSConnector.post") def test_malicious_url(mock_post): # Build a real httpx.Response to match the new return type import json diff --git a/ppp_connectors/tests/test_mongodb/test_unit_async_mongo.py b/src/apiary/tests/test_mongodb/test_unit_async_mongo.py similarity index 97% rename from ppp_connectors/tests/test_mongodb/test_unit_async_mongo.py rename to src/apiary/tests/test_mongodb/test_unit_async_mongo.py index 6bbc7bf..e47add0 100644 --- a/ppp_connectors/tests/test_mongodb/test_unit_async_mongo.py +++ b/src/apiary/tests/test_mongodb/test_unit_async_mongo.py @@ -3,7 +3,7 @@ import pytest from unittest.mock import AsyncMock -from ppp_connectors.dbms_connectors.mongo_async import AsyncMongoConnector +from apiary.dbms_connectors.mongo_async import AsyncMongoConnector @pytest.mark.asyncio diff --git a/ppp_connectors/tests/test_mongodb/test_unit_mongo.py b/src/apiary/tests/test_mongodb/test_unit_mongo.py similarity index 92% rename from ppp_connectors/tests/test_mongodb/test_unit_mongo.py rename to src/apiary/tests/test_mongodb/test_unit_mongo.py index 0ede1b1..17d5d71 100644 --- a/ppp_connectors/tests/test_mongodb/test_unit_mongo.py +++ b/src/apiary/tests/test_mongodb/test_unit_mongo.py @@ -1,7 +1,7 @@ import pytest from pymongo import UpdateOne from pymongo.errors import ServerSelectionTimeoutError -from ppp_connectors.dbms_connectors.mongo import MongoConnector +from apiary.dbms_connectors.mongo import MongoConnector from unittest.mock import patch, MagicMock @@ -10,7 +10,7 @@ def test_mongo_query(monkeypatch): fake_client = MagicMock() fake_client.admin.command.return_value = {"ok": 1} monkeypatch.setattr( - "ppp_connectors.dbms_connectors.mongo.MongoClient", + "apiary.dbms_connectors.mongo.MongoClient", MagicMock(return_value=fake_client), ) mock_cursor = [ @@ -37,7 +37,7 @@ def test_insert_many(monkeypatch): fake_client = MagicMock() fake_client.admin.command.return_value = {"ok": 1} monkeypatch.setattr( - "ppp_connectors.dbms_connectors.mongo.MongoClient", + "apiary.dbms_connectors.mongo.MongoClient", MagicMock(return_value=fake_client), ) mock_insert_many = MagicMock() @@ -63,7 +63,7 @@ def test_distinct(monkeypatch): fake_client = MagicMock() fake_client.admin.command.return_value = {"ok": 1} monkeypatch.setattr( - "ppp_connectors.dbms_connectors.mongo.MongoClient", + "apiary.dbms_connectors.mongo.MongoClient", MagicMock(return_value=fake_client), ) mock_collection = MagicMock() @@ -95,7 +95,7 @@ def test_aggregate(monkeypatch): fake_client.admin.command.return_value = {"ok": 1} fake_client.__getitem__.return_value.__getitem__.return_value = mock_collection monkeypatch.setattr( - "ppp_connectors.dbms_connectors.mongo.MongoClient", + "apiary.dbms_connectors.mongo.MongoClient", MagicMock(return_value=fake_client), ) @@ -117,7 +117,7 @@ def test_mongo_connection_failure(): -@patch("ppp_connectors.dbms_connectors.mongo.MongoClient") +@patch("apiary.dbms_connectors.mongo.MongoClient") def test_mongo_init_with_auth_and_ssl(mock_mongo_client): # Mock ping success on the returned client instance instance = MagicMock() @@ -143,7 +143,7 @@ def test_mongo_init_with_auth_and_ssl(mock_mongo_client): ) -@patch("ppp_connectors.dbms_connectors.mongo.MongoClient") +@patch("apiary.dbms_connectors.mongo.MongoClient") def test_mongo_init_defaults(mock_mongo_client): instance = MagicMock() instance.admin.command.return_value = {"ok": 1} @@ -157,7 +157,7 @@ def test_upsert_many_with_unique_key(monkeypatch): fake_client = MagicMock() fake_client.admin.command.return_value = {"ok": 1} monkeypatch.setattr( - "ppp_connectors.dbms_connectors.mongo.MongoClient", + "apiary.dbms_connectors.mongo.MongoClient", MagicMock(return_value=fake_client), ) mock_bulk_write = MagicMock() @@ -186,7 +186,7 @@ def test_upsert_many_raises_without_unique_key(monkeypatch): fake_client = MagicMock() fake_client.admin.command.return_value = {"ok": 1} monkeypatch.setattr( - "ppp_connectors.dbms_connectors.mongo.MongoClient", + "apiary.dbms_connectors.mongo.MongoClient", MagicMock(return_value=fake_client), ) connector = MongoConnector( @@ -208,7 +208,7 @@ def test_context_manager_closes_client(monkeypatch): fake_client = MagicMock() fake_client.admin.command.return_value = {"ok": 1} monkeypatch.setattr( - "ppp_connectors.dbms_connectors.mongo.MongoClient", + "apiary.dbms_connectors.mongo.MongoClient", MagicMock(return_value=fake_client), ) diff --git a/ppp_connectors/tests/test_odbc/test_unit_odbc.py b/src/apiary/tests/test_odbc/test_unit_odbc.py similarity index 92% rename from ppp_connectors/tests/test_odbc/test_unit_odbc.py rename to src/apiary/tests/test_odbc/test_unit_odbc.py index d5d8f98..fc87acd 100644 --- a/ppp_connectors/tests/test_odbc/test_unit_odbc.py +++ b/src/apiary/tests/test_odbc/test_unit_odbc.py @@ -2,13 +2,13 @@ import pytest -import ppp_connectors.dbms_connectors.odbc as odbc_module -from ppp_connectors.dbms_connectors.odbc import ODBCConnector +import apiary.dbms_connectors.odbc as odbc_module +from apiary.dbms_connectors.odbc import ODBCConnector @pytest.fixture def mock_pyodbc(): - with patch("ppp_connectors.dbms_connectors.odbc._get_pyodbc") as mock_loader: + with patch("apiary.dbms_connectors.odbc._get_pyodbc") as mock_loader: pyodbc_mock = MagicMock() mock_loader.return_value = pyodbc_mock yield pyodbc_mock diff --git a/ppp_connectors/tests/test_splunk/test_unit_splunk.py b/src/apiary/tests/test_splunk/test_unit_splunk.py similarity index 96% rename from ppp_connectors/tests/test_splunk/test_unit_splunk.py rename to src/apiary/tests/test_splunk/test_unit_splunk.py index fcd148c..594e300 100644 --- a/ppp_connectors/tests/test_splunk/test_unit_splunk.py +++ b/src/apiary/tests/test_splunk/test_unit_splunk.py @@ -1,7 +1,7 @@ import pytest import httpx from unittest.mock import patch, MagicMock -from ppp_connectors.dbms_connectors.splunk import SplunkConnector +from apiary.dbms_connectors.splunk import SplunkConnector @pytest.fixture diff --git a/ppp_connectors/tests/test_spycloud/cassettes/test_spycloud_ato_search_vcr.yaml b/src/apiary/tests/test_spycloud/cassettes/test_spycloud_ato_search_vcr.yaml similarity index 100% rename from ppp_connectors/tests/test_spycloud/cassettes/test_spycloud_ato_search_vcr.yaml rename to src/apiary/tests/test_spycloud/cassettes/test_spycloud_ato_search_vcr.yaml diff --git a/ppp_connectors/tests/test_spycloud/test_integration_spycloud.py b/src/apiary/tests/test_spycloud/test_integration_spycloud.py similarity index 85% rename from ppp_connectors/tests/test_spycloud/test_integration_spycloud.py rename to src/apiary/tests/test_spycloud/test_integration_spycloud.py index 9b6085e..ab4e4f1 100644 --- a/ppp_connectors/tests/test_spycloud/test_integration_spycloud.py +++ b/src/apiary/tests/test_spycloud/test_integration_spycloud.py @@ -1,6 +1,6 @@ import httpx import pytest -from ppp_connectors.api_connectors.spycloud import SpycloudConnector +from apiary.api_connectors.spycloud import SpycloudConnector @pytest.mark.integration def test_spycloud_ato_search_vcr(vcr_cassette): diff --git a/ppp_connectors/tests/test_spycloud/test_unit_async_spycloud.py b/src/apiary/tests/test_spycloud/test_unit_async_spycloud.py similarity index 95% rename from ppp_connectors/tests/test_spycloud/test_unit_async_spycloud.py rename to src/apiary/tests/test_spycloud/test_unit_async_spycloud.py index 53a9fc2..37dec52 100644 --- a/ppp_connectors/tests/test_spycloud/test_unit_async_spycloud.py +++ b/src/apiary/tests/test_spycloud/test_unit_async_spycloud.py @@ -1,6 +1,6 @@ import pytest import httpx -from ppp_connectors.api_connectors.spycloud import AsyncSpycloudConnector +from apiary.api_connectors.spycloud import AsyncSpycloudConnector @pytest.mark.asyncio async def test_async_init_with_env_keys(monkeypatch): diff --git a/ppp_connectors/tests/test_spycloud/test_unit_spycloud.py b/src/apiary/tests/test_spycloud/test_unit_spycloud.py similarity index 86% rename from ppp_connectors/tests/test_spycloud/test_unit_spycloud.py rename to src/apiary/tests/test_spycloud/test_unit_spycloud.py index 0924b71..b756ef6 100644 --- a/ppp_connectors/tests/test_spycloud/test_unit_spycloud.py +++ b/src/apiary/tests/test_spycloud/test_unit_spycloud.py @@ -2,7 +2,7 @@ import httpx import pytest from unittest.mock import patch, MagicMock -from ppp_connectors.api_connectors.spycloud import SpycloudConnector +from apiary.api_connectors.spycloud import SpycloudConnector def test_init_with_api_key(): @@ -18,14 +18,14 @@ def test_init_with_env_key(): assert connector.ato_key == "env_key" -@patch("ppp_connectors.api_connectors.broker.combine_env_configs", return_value={}) +@patch("apiary.api_connectors.broker.combine_env_configs", return_value={}) def test_init_missing_key(mock_env): connector = SpycloudConnector(load_env_vars=True) with pytest.raises(ValueError, match="SPYCLOUD_API_ATO_KEY is required for this request"): connector.ato_search(search_type="email", query="test@example.com") -@patch("ppp_connectors.api_connectors.spycloud.SpycloudConnector._make_request") +@patch("apiary.api_connectors.spycloud.SpycloudConnector._make_request") def test_ato_search(mock_request): # Build a real httpx.Response to match new return type (raw Response) request = httpx.Request("GET", "https://api.spycloud.io/sp-v2/breach/data/emails/test@example.com") diff --git a/ppp_connectors/tests/test_twilio/cassettes/test_lookup_phone_vcr.yaml b/src/apiary/tests/test_twilio/cassettes/test_lookup_phone_vcr.yaml similarity index 100% rename from ppp_connectors/tests/test_twilio/cassettes/test_lookup_phone_vcr.yaml rename to src/apiary/tests/test_twilio/cassettes/test_lookup_phone_vcr.yaml diff --git a/ppp_connectors/tests/test_twilio/test_integration_twilio.py b/src/apiary/tests/test_twilio/test_integration_twilio.py similarity index 87% rename from ppp_connectors/tests/test_twilio/test_integration_twilio.py rename to src/apiary/tests/test_twilio/test_integration_twilio.py index ad5c8ff..22b83a7 100644 --- a/ppp_connectors/tests/test_twilio/test_integration_twilio.py +++ b/src/apiary/tests/test_twilio/test_integration_twilio.py @@ -2,7 +2,7 @@ import httpx import pytest import vcr -from ppp_connectors.api_connectors.twilio import TwilioConnector +from apiary.api_connectors.twilio import TwilioConnector @pytest.mark.integration def test_lookup_phone_vcr(vcr_cassette): diff --git a/ppp_connectors/tests/test_twilio/test_unit_async_twilio.py b/src/apiary/tests/test_twilio/test_unit_async_twilio.py similarity index 87% rename from ppp_connectors/tests/test_twilio/test_unit_async_twilio.py rename to src/apiary/tests/test_twilio/test_unit_async_twilio.py index 4c1689d..0805456 100644 --- a/ppp_connectors/tests/test_twilio/test_unit_async_twilio.py +++ b/src/apiary/tests/test_twilio/test_unit_async_twilio.py @@ -1,7 +1,7 @@ import pytest import httpx from unittest.mock import patch, AsyncMock -from ppp_connectors.api_connectors.twilio import AsyncTwilioConnector +from apiary.api_connectors.twilio import AsyncTwilioConnector @pytest.mark.asyncio async def test_async_init_with_env(monkeypatch): @@ -18,7 +18,7 @@ async def test_async_lookup_phone_raises_for_invalid_packages(): with pytest.raises(ValueError, match="Invalid data packages: badpkg"): await connector.lookup_phone("+14155552671", data_packages=["badpkg"]) -@patch("ppp_connectors.api_connectors.twilio.AsyncTwilioConnector._make_request", new_callable=AsyncMock) +@patch("apiary.api_connectors.twilio.AsyncTwilioConnector._make_request", new_callable=AsyncMock) @pytest.mark.asyncio async def test_async_lookup_phone_calls_make_request(mock_request): mock_resp = httpx.Response(200, content=b'{"valid": true}') diff --git a/ppp_connectors/tests/test_twilio/test_unit_twilio.py b/src/apiary/tests/test_twilio/test_unit_twilio.py similarity index 85% rename from ppp_connectors/tests/test_twilio/test_unit_twilio.py rename to src/apiary/tests/test_twilio/test_unit_twilio.py index 3d84c88..b62107c 100644 --- a/ppp_connectors/tests/test_twilio/test_unit_twilio.py +++ b/src/apiary/tests/test_twilio/test_unit_twilio.py @@ -1,7 +1,7 @@ import httpx import pytest from unittest.mock import patch, MagicMock -from ppp_connectors.api_connectors.twilio import TwilioConnector +from apiary.api_connectors.twilio import TwilioConnector def test_init_with_all_keys(): @@ -17,13 +17,13 @@ def test_init_with_env_keys(): assert connector.auth is not None -@patch("ppp_connectors.api_connectors.broker.combine_env_configs", return_value={}) +@patch("apiary.api_connectors.broker.combine_env_configs", return_value={}) def test_init_missing_auth_keys(mock_env): with pytest.raises(ValueError, match="TWILIO_API_SID and TWILIO_API_SECRET are required"): TwilioConnector(load_env_vars=True) -@patch("ppp_connectors.api_connectors.twilio.TwilioConnector._make_request") +@patch("apiary.api_connectors.twilio.TwilioConnector._make_request") def test_lookup_phone(mock_request): import json # Return a real httpx.Response to reflect new return type diff --git a/ppp_connectors/tests/test_urlscan/cassettes/test_urlscan_results_vcr.yaml b/src/apiary/tests/test_urlscan/cassettes/test_urlscan_results_vcr.yaml similarity index 100% rename from ppp_connectors/tests/test_urlscan/cassettes/test_urlscan_results_vcr.yaml rename to src/apiary/tests/test_urlscan/cassettes/test_urlscan_results_vcr.yaml diff --git a/ppp_connectors/tests/test_urlscan/test_integration_urlscan.py b/src/apiary/tests/test_urlscan/test_integration_urlscan.py similarity index 85% rename from ppp_connectors/tests/test_urlscan/test_integration_urlscan.py rename to src/apiary/tests/test_urlscan/test_integration_urlscan.py index 80c6a1d..fdae573 100644 --- a/ppp_connectors/tests/test_urlscan/test_integration_urlscan.py +++ b/src/apiary/tests/test_urlscan/test_integration_urlscan.py @@ -1,6 +1,6 @@ import httpx import pytest -from ppp_connectors.api_connectors.urlscan import URLScanConnector +from apiary.api_connectors.urlscan import URLScanConnector @pytest.mark.integration def test_urlscan_results_vcr(vcr_cassette): diff --git a/ppp_connectors/tests/test_urlscan/test_unit_async_urlscan.py b/src/apiary/tests/test_urlscan/test_unit_async_urlscan.py similarity index 95% rename from ppp_connectors/tests/test_urlscan/test_unit_async_urlscan.py rename to src/apiary/tests/test_urlscan/test_unit_async_urlscan.py index f5f2250..58a2a58 100644 --- a/ppp_connectors/tests/test_urlscan/test_unit_async_urlscan.py +++ b/src/apiary/tests/test_urlscan/test_unit_async_urlscan.py @@ -1,7 +1,7 @@ import pytest from httpx import Response from httpx import Request -from ppp_connectors.api_connectors.urlscan import AsyncURLScanConnector +from apiary.api_connectors.urlscan import AsyncURLScanConnector @pytest.mark.asyncio async def test_async_init_with_api_key(): diff --git a/ppp_connectors/tests/test_urlscan/test_unit_urlscan.py b/src/apiary/tests/test_urlscan/test_unit_urlscan.py similarity index 84% rename from ppp_connectors/tests/test_urlscan/test_unit_urlscan.py rename to src/apiary/tests/test_urlscan/test_unit_urlscan.py index 345681b..9c9916d 100644 --- a/ppp_connectors/tests/test_urlscan/test_unit_urlscan.py +++ b/src/apiary/tests/test_urlscan/test_unit_urlscan.py @@ -1,7 +1,7 @@ import httpx import pytest from unittest.mock import patch, MagicMock -from ppp_connectors.api_connectors.urlscan import URLScanConnector +from apiary.api_connectors.urlscan import URLScanConnector def test_init_with_api_key(): connector = URLScanConnector(api_key="test_key") @@ -12,12 +12,12 @@ def test_init_with_env_key(): connector = URLScanConnector(load_env_vars=True) assert connector.api_key == "env_key" -@patch("ppp_connectors.api_connectors.broker.combine_env_configs", return_value={}) +@patch("apiary.api_connectors.broker.combine_env_configs", return_value={}) def test_init_missing_auth_keys(mock_env): with pytest.raises(ValueError, match="API key is required for URLScanConnector"): URLScanConnector(load_env_vars=True) -@patch("ppp_connectors.api_connectors.urlscan.URLScanConnector.get") +@patch("apiary.api_connectors.urlscan.URLScanConnector.get") def test_results(mock_get): import json