diff --git a/README.md b/README.md index 9c91bc2..322606f 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,10 @@

The perfect starting point to integrate Openapi® within your Python project

[![Build](https://github.com/openapi/openapi-python-sdk/actions/workflows/python.yml/badge.svg)](https://github.com/openapi/openapi-python-sdk/actions/workflows/python.yml) -[![PyPI Version](https://img.shields.io/pypi/v/openapi-python-sdk)](https://pypi.org/project/openapi-python-sdk/) -[![Python Versions](https://img.shields.io/badge/python-%3E%3D3.10-blue)](https://pypi.org/project/openapi-python-sdk/) +[![PyPI Version](https://img.shields.io/pypi/v/openapi-sdk)](https://pypi.org/project/openapi-sdk/) +[![Python Versions](https://img.shields.io/badge/python-%3E%3D3.10-blue)](https://pypi.org/project/openapi-sdk/) [![License](https://img.shields.io/github/license/openapi/openapi-python-sdk)](LICENSE) -[![Downloads](https://img.shields.io/pypi/dm/openapi-python-sdk)](https://pypi.org/project/openapi-python-sdk/) +[![Downloads](https://img.shields.io/pypi/dm/openapi-sdk)](https://pypi.org/project/openapi-sdk/)
[![Linux Foundation Member](https://img.shields.io/badge/Linux%20Foundation-Silver%20Member-003778?logo=linux-foundation&logoColor=white)](https://www.linuxfoundation.org/about/members) @@ -47,17 +47,17 @@ For a complete list of all available services, check out the [Openapi Marketplac ## Installation -The package is available on [PyPI](https://pypi.org/project/openapi-python-sdk/) and supports Python 3.10 and above. +The package is available on [PyPI](https://pypi.org/project/openapi-sdk/) and supports Python 3.10 and above. Install it with pip: ```bash -pip install openapi-python-sdk +pip install openapi-sdk ``` If you are using Poetry: ```bash -poetry add openapi-python-sdk +poetry add openapi-sdk ``` No additional configuration is needed. The only runtime dependency is [`httpx`](https://www.python-httpx.org/). @@ -71,7 +71,7 @@ Interaction with the Openapi platform happens in two distinct steps. Authenticate with your credentials and obtain a short-lived bearer token scoped to the endpoints you need. ```python -from openapi_python_sdk import OauthClient +from openapi_sdk import OauthClient oauth = OauthClient(username="", apikey="", test=True) @@ -93,7 +93,7 @@ oauth.delete_token(id=token) Use the token to make authenticated requests to any Openapi service. ```python -from openapi_python_sdk import Client +from openapi_sdk import Client client = Client(token=token) @@ -119,7 +119,7 @@ If you need to configure custom retry logic, proxies, or use a different HTTP cl ```python from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry -from openapi_python_sdk import Client +from openapi_sdk import Client import requests retry = Retry(total=3) @@ -139,7 +139,7 @@ By default, the SDK uses a 30-second timeout for all network requests to avoid h You can easily override it passing a `timeout` explicitly during initialization to all client variants: ```python -from openapi_python_sdk import Client +from openapi_sdk import Client client = Client(token="token", timeout=60.0) # 60 seconds ``` @@ -151,7 +151,7 @@ The SDK provides `AsyncClient` and `AsyncOauthClient` for use with asynchronous ### Async Authentication ```python -from openapi_python_sdk import AsyncOauthClient +from openapi_sdk import AsyncOauthClient async with AsyncOauthClient(username="", apikey="", test=True) as oauth: resp = await oauth.create_token( @@ -164,7 +164,7 @@ async with AsyncOauthClient(username="", apikey="", ### Async Requests ```python -from openapi_python_sdk import AsyncClient +from openapi_sdk import AsyncClient async with AsyncClient(token=token) as client: resp = await client.request( diff --git a/docs/readme-pypi.md b/docs/readme-pypi.md index fd93bb6..9b76f67 100644 --- a/docs/readme-pypi.md +++ b/docs/readme-pypi.md @@ -1,4 +1,4 @@ -# openapi-python-sdk +# openapi-sdk A minimal Python SDK for [Openapi®](https://openapi.it) — the largest certified API marketplace in Italy. Provides the core HTTP primitives to authenticate and interact with any Openapi service, without API-specific coupling. @@ -11,7 +11,7 @@ Provides the core HTTP primitives to authenticate and interact with any Openapi ## Installation ```bash -pip install openapi-python-sdk +pip install openapi-sdk ``` ## Usage @@ -21,7 +21,7 @@ Interaction with the Openapi platform happens in two distinct steps. ### Step 1 — Generate a token ```python -from openapi_python_sdk.client import OauthClient +from openapi_sdk.client import OauthClient oauth = OauthClient(username="", apikey="", test=True) @@ -41,7 +41,7 @@ oauth.delete_token(id=token) ### Step 2 — Call an API endpoint ```python -from openapi_python_sdk.client import Client +from openapi_sdk.client import Client client = Client(token=token) @@ -65,7 +65,7 @@ resp = client.request( By default, the SDK uses a 30-second timeout for all network requests. You can easily override it passing a `timeout` explicitly during initialization: ```python -from openapi_python_sdk.client import Client +from openapi_sdk.client import Client client = Client(token="token", timeout=60.0) # 60 seconds ``` diff --git a/examples/api_calls.py b/examples/api_calls.py index 990becc..050b9ea 100644 --- a/examples/api_calls.py +++ b/examples/api_calls.py @@ -10,7 +10,7 @@ import os -from openapi_python_sdk.client import Client +from openapi_sdk.client import Client token = os.environ.get("OPENAPI_TOKEN", "") diff --git a/examples/token_generation.py b/examples/token_generation.py index 0d29053..ffce00f 100644 --- a/examples/token_generation.py +++ b/examples/token_generation.py @@ -10,7 +10,7 @@ import os -from openapi_python_sdk.client import OauthClient +from openapi_sdk.client import OauthClient username = os.environ.get("OPENAPI_USERNAME", "") apikey = os.environ.get("OPENAPI_APIKEY", "") diff --git a/openapi_python_sdk/__init__.py b/openapi_sdk/__init__.py similarity index 100% rename from openapi_python_sdk/__init__.py rename to openapi_sdk/__init__.py diff --git a/openapi_python_sdk/async_client.py b/openapi_sdk/async_client.py similarity index 100% rename from openapi_python_sdk/async_client.py rename to openapi_sdk/async_client.py diff --git a/openapi_python_sdk/async_oauth_client.py b/openapi_sdk/async_oauth_client.py similarity index 100% rename from openapi_python_sdk/async_oauth_client.py rename to openapi_sdk/async_oauth_client.py diff --git a/openapi_python_sdk/client.py b/openapi_sdk/client.py similarity index 100% rename from openapi_python_sdk/client.py rename to openapi_sdk/client.py diff --git a/openapi_python_sdk/oauth_client.py b/openapi_sdk/oauth_client.py similarity index 100% rename from openapi_python_sdk/oauth_client.py rename to openapi_sdk/oauth_client.py diff --git a/pyproject.toml b/pyproject.toml index ac21072..aa00751 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,10 @@ [tool.poetry] -name = "openapi-python-sdk" +name = "openapi-sdk" version = "0.3.0" description = "A minimal Python SDK for the Openapi® API marketplace" authors = ["Michael Cuffaro "] readme = "docs/readme-pypi.md" -packages = [{include = "openapi_python_sdk"}] +packages = [{include = "openapi_sdk"}] [tool.poetry.dependencies] python = "^3.10" diff --git a/tests/test_async_client.py b/tests/test_async_client.py index 461305b..df1eb07 100644 --- a/tests/test_async_client.py +++ b/tests/test_async_client.py @@ -1,7 +1,7 @@ import unittest from unittest.mock import AsyncMock, MagicMock, patch -from openapi_python_sdk.client import AsyncClient, AsyncOauthClient +from openapi_sdk.client import AsyncClient, AsyncOauthClient class TestAsyncOauthClient(unittest.IsolatedAsyncioTestCase): @@ -10,7 +10,7 @@ class TestAsyncOauthClient(unittest.IsolatedAsyncioTestCase): which allows for native await calls in test methods. """ - @patch("openapi_python_sdk.client.httpx.AsyncClient") + @patch("openapi_sdk.client.httpx.AsyncClient") async def test_create_token(self, mock_httpx): # Mocking the response and the post method mock_resp = MagicMock() @@ -27,7 +27,7 @@ async def test_create_token(self, mock_httpx): # Verify aclose was called by the context manager mock_httpx.return_value.aclose.assert_called_once() - @patch("openapi_python_sdk.client.httpx.AsyncClient") + @patch("openapi_sdk.client.httpx.AsyncClient") async def test_get_scopes(self, mock_httpx): mock_resp = MagicMock() mock_resp.json.return_value = {"scopes": ["GET:test.example.com/api"]} @@ -53,7 +53,7 @@ class TestAsyncClient(unittest.IsolatedAsyncioTestCase): Test suite for the generic AsyncClient. """ - @patch("openapi_python_sdk.client.httpx.AsyncClient") + @patch("openapi_sdk.client.httpx.AsyncClient") async def test_request_get(self, mock_httpx): mock_resp = MagicMock() mock_resp.json.return_value = {"data": []} @@ -71,7 +71,7 @@ async def test_request_get(self, mock_httpx): mock_httpx.return_value.request.assert_called_once() mock_httpx.return_value.aclose.assert_called_once() - @patch("openapi_python_sdk.client.httpx.AsyncClient") + @patch("openapi_sdk.client.httpx.AsyncClient") async def test_request_post(self, mock_httpx): mock_resp = MagicMock() mock_resp.json.return_value = {"result": "ok"} diff --git a/tests/test_client.py b/tests/test_client.py index 3b8f874..f61cd84 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -1,12 +1,12 @@ import unittest from unittest.mock import MagicMock, patch -from openapi_python_sdk.client import Client, OauthClient +from openapi_sdk.client import Client, OauthClient class TestOauthClient(unittest.TestCase): - @patch("openapi_python_sdk.client.httpx.Client") + @patch("openapi_sdk.client.httpx.Client") def test_create_token(self, mock_httpx): mock_resp = MagicMock() mock_resp.json.return_value = {"token": "abc123"} @@ -18,7 +18,7 @@ def test_create_token(self, mock_httpx): self.assertEqual(resp["token"], "abc123") mock_httpx.return_value.post.assert_called_once() - @patch("openapi_python_sdk.client.httpx.Client") + @patch("openapi_sdk.client.httpx.Client") def test_delete_token(self, mock_httpx): mock_resp = MagicMock() mock_resp.json.return_value = {"success": True} @@ -30,7 +30,7 @@ def test_delete_token(self, mock_httpx): self.assertTrue(resp["success"]) mock_httpx.return_value.delete.assert_called_once() - @patch("openapi_python_sdk.client.httpx.Client") + @patch("openapi_sdk.client.httpx.Client") def test_get_scopes(self, mock_httpx): mock_resp = MagicMock() mock_resp.json.return_value = {"scopes": ["GET:test.example.com/api"]} @@ -41,17 +41,17 @@ def test_get_scopes(self, mock_httpx): self.assertIn("scopes", resp) - @patch("openapi_python_sdk.client.httpx.Client") + @patch("openapi_sdk.client.httpx.Client") def test_uses_sandbox_url_when_test_true(self, mock_httpx): oauth = OauthClient(username="user", apikey="key", test=True) self.assertIn("test.", oauth.url) - @patch("openapi_python_sdk.client.httpx.Client") + @patch("openapi_sdk.client.httpx.Client") def test_uses_production_url_by_default(self, mock_httpx): oauth = OauthClient(username="user", apikey="key") self.assertNotIn("test.", oauth.url) - @patch("openapi_python_sdk.client.httpx.Client") + @patch("openapi_sdk.client.httpx.Client") def test_auth_header_is_basic(self, mock_httpx): oauth = OauthClient(username="user", apikey="key") self.assertTrue(oauth.auth_header.startswith("Basic ")) @@ -64,7 +64,7 @@ def test_custom_client_transport(self): class TestClient(unittest.TestCase): - @patch("openapi_python_sdk.client.httpx.Client") + @patch("openapi_sdk.client.httpx.Client") def test_request_get(self, mock_httpx): mock_resp = MagicMock() mock_resp.json.return_value = {"data": []} @@ -80,7 +80,7 @@ def test_request_get(self, mock_httpx): self.assertEqual(resp, {"data": []}) mock_httpx.return_value.request.assert_called_once() - @patch("openapi_python_sdk.client.httpx.Client") + @patch("openapi_sdk.client.httpx.Client") def test_request_post(self, mock_httpx): mock_resp = MagicMock() mock_resp.json.return_value = {"result": "ok"} @@ -95,13 +95,13 @@ def test_request_post(self, mock_httpx): self.assertEqual(resp["result"], "ok") - @patch("openapi_python_sdk.client.httpx.Client") + @patch("openapi_sdk.client.httpx.Client") def test_auth_header(self, mock_httpx): client = Client(token="mytoken") self.assertEqual(client.auth_header, "Bearer mytoken") self.assertEqual(client.headers["Authorization"], "Bearer mytoken") - @patch("openapi_python_sdk.client.httpx.Client") + @patch("openapi_sdk.client.httpx.Client") def test_defaults_on_empty_request(self, mock_httpx): mock_resp = MagicMock() mock_resp.json.return_value = {} diff --git a/tests/test_thread_safety.py b/tests/test_thread_safety.py index 5763084..d7c55a7 100644 --- a/tests/test_thread_safety.py +++ b/tests/test_thread_safety.py @@ -3,7 +3,7 @@ import httpx -from openapi_python_sdk import Client, OauthClient +from openapi_sdk import Client, OauthClient class TestThreadSafety(unittest.TestCase):