Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
<h4>The perfect starting point to integrate <a href="https://openapi.com/">Openapi®</a> within your Python project</h4>

[![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/)
<br>
[![Linux Foundation Member](https://img.shields.io/badge/Linux%20Foundation-Silver%20Member-003778?logo=linux-foundation&logoColor=white)](https://www.linuxfoundation.org/about/members)
</div>
Expand Down Expand Up @@ -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/).
Expand All @@ -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="<your_username>", apikey="<your_apikey>", test=True)

Expand All @@ -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)

Expand All @@ -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)
Expand All @@ -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
```
Expand All @@ -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="<your_username>", apikey="<your_apikey>", test=True) as oauth:
resp = await oauth.create_token(
Expand All @@ -164,7 +164,7 @@ async with AsyncOauthClient(username="<your_username>", apikey="<your_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(
Expand Down
10 changes: 5 additions & 5 deletions docs/readme-pypi.md
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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
Expand All @@ -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="<your_username>", apikey="<your_apikey>", test=True)

Expand All @@ -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)

Expand All @@ -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
```
Expand Down
2 changes: 1 addition & 1 deletion examples/api_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -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", "<your_token>")

Expand Down
2 changes: 1 addition & 1 deletion examples/token_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -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", "<your_username>")
apikey = os.environ.get("OPENAPI_APIKEY", "<your_apikey>")
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -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 <michael@cuffaro.com>"]
readme = "docs/readme-pypi.md"
packages = [{include = "openapi_python_sdk"}]
packages = [{include = "openapi_sdk"}]

[tool.poetry.dependencies]
python = "^3.10"
Expand Down
10 changes: 5 additions & 5 deletions tests/test_async_client.py
Original file line number Diff line number Diff line change
@@ -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):
Expand All @@ -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()
Expand All @@ -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"]}
Expand All @@ -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": []}
Expand All @@ -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"}
Expand Down
22 changes: 11 additions & 11 deletions tests/test_client.py
Original file line number Diff line number Diff line change
@@ -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"}
Expand All @@ -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}
Expand All @@ -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"]}
Expand All @@ -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 "))
Expand All @@ -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": []}
Expand All @@ -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"}
Expand All @@ -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 = {}
Expand Down
2 changes: 1 addition & 1 deletion tests/test_thread_safety.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import httpx

from openapi_python_sdk import Client, OauthClient
from openapi_sdk import Client, OauthClient


class TestThreadSafety(unittest.TestCase):
Expand Down
Loading