From 9499c7e87be1876a547984acbe86669f710d8362 Mon Sep 17 00:00:00 2001 From: francesco Date: Tue, 9 Dec 2025 17:23:32 +0100 Subject: [PATCH 01/13] chore: init quality maintenance --- .github/REPOINFO.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .github/REPOINFO.txt diff --git a/.github/REPOINFO.txt b/.github/REPOINFO.txt new file mode 100644 index 0000000..e69de29 From 4ec4e0da7584278f21c6456c78d87fc5828d9748 Mon Sep 17 00:00:00 2001 From: francesco Date: Wed, 18 Mar 2026 10:51:48 +0100 Subject: [PATCH 02/13] restyle README files --- .github/assets/repo-header-a3.png | Bin 0 -> 86980 bytes .idea/.gitignore | 8 +++ .idea/modules.xml | 8 +++ .idea/openapi-python-sdk.iml | 12 ++++ .idea/vcs.xml | 6 ++ Makefile | 63 ++++++++++++++++++++ README.md | 96 ++++++++++++++++++++++++++++++ docs/code-of-conduct.md | 30 ++++++++++ docs/contributing.md | 45 ++++++++++++++ 9 files changed, 268 insertions(+) create mode 100644 .github/assets/repo-header-a3.png create mode 100644 .idea/.gitignore create mode 100644 .idea/modules.xml create mode 100644 .idea/openapi-python-sdk.iml create mode 100644 .idea/vcs.xml create mode 100644 Makefile create mode 100644 docs/code-of-conduct.md create mode 100644 docs/contributing.md diff --git a/.github/assets/repo-header-a3.png b/.github/assets/repo-header-a3.png new file mode 100644 index 0000000000000000000000000000000000000000..9cd8a8bd9da5470a31f1653cb9a40851780fbe64 GIT binary patch literal 86980 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%0A*;<=%0gxMm+TA49B- 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�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 JwVBr*;%M3IA3DDU7jFDK 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

H$f@i2vnI6S{DG41 zs$|uZY7L<+D|+L}mhlE^G!X1Tky%6{@~!YVD`$D0GwqY@Ls#@Ai^jeBGi{GZo6PE8 zSvYpuHd6OEFVuf=-lIC%Nqy{LS|?YeRRc_W=6SQD_o9C*vU&Wi(A1(Tl2(TH`)Kb7 z57yeEwe?J=vwT+mtL3RO(Eq)B#G8BxPm%{q&ylfm)p~PBh1(iDk=*GE& zbA)bQf4%b~y#6d;Kb@^;MSap~&{d98?svz3K>qI~=^gQ(Cwl)~c-!%oE$9CPHL(*F z=pV3>!_-ogGFsb}lc)Mz9a=O*hyAZTB7(AmE!_V24Iq392tQH%yiqbf0>HO$0H7}c z;5z{LrBE>XDi(^@$O}!@g7rRRUh!C6QTMKA=(V=xl_|6RK}+}0(JG+cEx!^KTGc@| zqWdBHVs@L&3jZJ5Skugp*B0^d99TOvrQBIS7jNr)iOOSkO?oZ;?@DlWW!_!K$gIwL z^wn9t8Q}DxQgQG4Fllu?8|!U0{ZjXo@N#qxwL2LTHR`)`=_n{|@OzMLZ&7iNzZ(Gj z0s!9u!k2*fDFA*8fRD1?{{vqcgEgvD3(Noj0338hSafh?W;#K2bZBpK08L?ZbY*WK zL}?&LX<=h;ZErF4d6obG0BUqaSaf)8a5_VBWnpx0a#U|`Yyd-HZgycHC{kr^WMy(? zaw#BWZ(}_~K}RrGL0V2WFhL-7b7gWpRY65gQ)gOsZ&pnpVsc?_WIa@6VQnByVRCC_ rbZKs9AT1zAa$#m^V{agIWo>Y5VRU6ZDU)G400000NkvXXu0mjf+YhwG literal 0 HcmV?d00001 diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e02b938 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/openapi-python-sdk.iml b/.idea/openapi-python-sdk.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/openapi-python-sdk.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a35e742 --- /dev/null +++ b/Makefile @@ -0,0 +1,63 @@ +#!make + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# # +# ____ _ # +# / __ \____ ___ ____ ____ _____ (_) ® # +# / / / / __ \/ _ \/ __ \/ __ `/ __ \/ / # +# / /_/ / /_/ / __/ / / / /_/ / /_/ / / # +# \____/ .___/\___/_/ /_/\__,_/ .___/_/ # +# /_/ /_/ # +# # +# The Largest Certified API Marketplace # +# Accelerate Digital Transformation • Simplify Processes • Lead Industry # +# # +# ═══════════════════════════════════════════════════════════════════════ # +# # +# Project: openapi-rust-sdk # +# Version: 0.1.0 # +# Author: Michael Cuffaro (@maiku1008) # +# Copyright: (c) 2025 Openapi®. All rights reserved. # +# License: MIT # +# Maintainer: Francesco Bianco # +# Contact: https://openapi.com/ # +# Repository: https://github.com/openapi/openapi-php-sdk/ # +# Documentation: https://console.openapi.com/ # +# # +# ═══════════════════════════════════════════════════════════════════════ # +# # +# "Truth lies at the source of the stream." # +# — English Proverb # +# # +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +## ========= +## Variables +## ========= + +VERSION := 1.2.1 + +## ==================== +## Development Commands +## ==================== + +dev-push: + @git config credential.helper 'cache --timeout=3600' + @git add . + @git commit -m "$$(read -p 'Commit message: ' msg; echo $$msg)" || true + @git push + +## ================ +## Release Commands +## ================ + +push: + @git add . + @git commit -am "Updated at $$(date)" || true + @git push + +release: push + @git add . + @git commit -m "Update PHP SDK to version ${VERSION}" || echo "No changes to commit" + @git tag -fa "${VERSION}" -m "${VERSION}" + @git push origin --tags -f \ No newline at end of file diff --git a/README.md b/README.md index 4031a9e..ea55a28 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,50 @@ +

+ + Openapi SDK for PHP + + +

Openapi® client for PHP

+

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

+ +[![Build Status](https://github.com/openapi/openapi-php-sdk/actions/workflows/php.yml/badge.svg)](https://github.com/openapi/openapi-php-sdk/actions/workflows/php.yml) +[![Packagist Version](https://img.shields.io/packagist/v/openapi/openapi-sdk)](https://packagist.org/packages/openapi/openapi-sdk) +[![PHP Version](https://img.shields.io/packagist/php-v/openapi/openapi-sdk)](https://packagist.org/packages/openapi/openapi-sdk) +[![License](https://img.shields.io/github/license/openapi/openapi-php-sdk?v=2)](LICENSE) +[![Downloads](https://img.shields.io/packagist/dt/openapi/openapi-sdk)](https://packagist.org/packages/openapi/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) +
+ +## Overview + +A minimal and agnostic PHP SDK for Openapi, inspired by a clean client implementation. This SDK provides only the core HTTP primitives needed to interact with any Openapi service. + +## Pre-requisites + +Before using the Openapi PHP Client, you will need an account at [Openapi](https://console.openapi.com/) and an API key to the sandbox and/or production environment + +## Features + +- **Agnostic Design**: No API-specific classes, works with any OpenAPI service +- **Minimal Dependencies**: Only requires PHP 8.0+ and cURL +- **OAuth Support**: Built-in OAuth client for token management +- **HTTP Primitives**: GET, POST, PUT, DELETE, PATCH methods +- **Clean Interface**: Similar to the Rust SDK design + +## What you can do + +With the Openapi PHP Client, you can easily interact with a variety of services in the Openapi Marketplace. For example, you can: + +- 📩 **Send SMS messages** with delivery reports and custom sender IDs +- 💸 **Process bills and payments** in real time via API +- 🧾 **Send electronic invoices** securely to the Italian Revenue Agency +- 📄 **Generate PDFs** from HTML content, including JavaScript rendering +- ✉️ **Manage certified emails** and legal communications via Italian Legalmail + +For a complete list of all available services, check out the [Openapi Marketplace](https://console.openapi.com/) 🌐 + + + # OpenApi IT Python Client @@ -75,3 +122,52 @@ Please adhere to this project's `code of conduct`. - [@maiku1008](https://www.github.com/maiku1008) - [@openapi-it](https://github.com/openapi-it) + + + + +## Contributing + +Contributions are always welcome! Whether you want to report bugs, suggest new features, improve documentation, or contribute code, your help is appreciated. + +See [docs/contributing.md](docs/contributing.md) for detailed instructions on how to get started. Please make sure to follow this project's [docs/code-of-conduct.md](docs/code-of-conduct.md) to help maintain a welcoming and collaborative environment. + +## Authors + +Meet the project authors: + +- L. Paderi ([@lpaderiAltravia](https://www.github.com/lpaderiAltravia)) +- Openapi Team ([@openapi-it](https://github.com/openapi-it)) + +## Partners + +Meet our partners using Openapi or contributing to this SDK: + +- [Blank](https://www.blank.app/) +- [Credit Safe](https://www.creditsafe.com/) +- [Deliveroo](https://deliveroo.it/) +- [Gruppo MOL](https://molgroupitaly.it/it/) +- [Jakala](https://www.jakala.com/) +- [Octotelematics](https://www.octotelematics.com/) +- [OTOQI](https://otoqi.com/) +- [PWC](https://www.pwc.com/) +- [QOMODO S.R.L.](https://www.qomodo.me/) +- [SOUNDREEF S.P.A.](https://www.soundreef.com/) + +## Our Commitments + +We believe in open source and we act on that belief. We became Silver Members +of the Linux Foundation because we wanted to formally support the ecosystem +we build on every day. Open standards, open collaboration, and open governance +are part of how we work and how we think about software. + +## License + +This project is licensed under the [MIT License](LICENSE). + +The MIT License is a permissive open-source license that allows you to freely use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software, provided that the original copyright notice and this permission notice are included in all copies or substantial portions of the software. + +In short, you are free to use this SDK in your personal, academic, or commercial projects, with minimal restrictions. The project is provided "as-is", without any warranty of any kind, either expressed or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non-infringement. + +For more details, see the full license text at the [MIT License page](https://choosealicense.com/licenses/mit/). + diff --git a/docs/code-of-conduct.md b/docs/code-of-conduct.md new file mode 100644 index 0000000..8908ea2 --- /dev/null +++ b/docs/code-of-conduct.md @@ -0,0 +1,30 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project a harassment-free experience for everyone. + +## Our Standards + +Examples of positive behavior: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy toward other community members + +Examples of unacceptable behavior: + +- Harassment, intimidation, or discrimination +- Public or private insults and derogatory comments +- Publishing others’ private information without consent +- Any other conduct reasonably considered inappropriate + +## Enforcement + +Instances of unacceptable behavior may be reported by contacting the project team at ``. All complaints will be reviewed promptly and fairly. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1. diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 0000000..48a76f4 --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,45 @@ +# Contributing to OpenApi IT Python SDK + +Thanks for considering contributing! 🎉 +We welcome all kinds of contributions: bug reports, feature requests, documentation improvements, and code enhancements. + +## How to Contribute + +1. **Fork the repository** and clone it locally: + ```bash + git clone https://github.com//.git + ``` + +2. **Create a branch** for your feature or fix: + ```bash + git checkout -b feature/your-feature-name + ``` + +3. **Make your changes** and commit them: + ```bash + git commit -m "Add some feature" + ``` + +4. **Push your branch** to your fork: + ```bash + git push origin feature/your-feature-name + ``` + +5. **Open a Pull Request** describing your changes. + +## Guidelines + +* Follow the existing **Python coding style**. +* Include **tests** for new features or bug fixes when applicable. +* Keep **commit messages clear and concise**. +* Update **documentation** as needed for your changes. + +## Reporting Issues + +To report bugs or request features, please **open an issue** on GitHub including: + +* Clear description of the problem or feature. +* Steps to reproduce (if applicable). +* Relevant logs or screenshots. + +Thank you for helping improve OpenApi IT Python SDK! 🚀 \ No newline at end of file From 23cfe21c8a438624584444b4b198d9621ba5ddd2 Mon Sep 17 00:00:00 2001 From: francesco Date: Wed, 18 Mar 2026 10:53:10 +0100 Subject: [PATCH 03/13] ignore ide files --- .gitignore | 4 ++++ .idea/.gitignore | 8 -------- .idea/modules.xml | 8 -------- .idea/openapi-python-sdk.iml | 12 ------------ .idea/vcs.xml | 6 ------ 5 files changed, 4 insertions(+), 34 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/modules.xml delete mode 100644 .idea/openapi-python-sdk.iml delete mode 100644 .idea/vcs.xml diff --git a/.gitignore b/.gitignore index 4f5d603..e8642d6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# IDEs and editors +.idea/ +.vscode/ + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index e02b938..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/openapi-python-sdk.iml b/.idea/openapi-python-sdk.iml deleted file mode 100644 index 24643cc..0000000 --- a/.idea/openapi-python-sdk.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From b8824e0a2124af9267b47cb639faa6a77b198da4 Mon Sep 17 00:00:00 2001 From: francesco Date: Wed, 18 Mar 2026 10:59:00 +0100 Subject: [PATCH 04/13] fix mispelled PHP --- README.md | 44 +++++++++++--------------------------------- 1 file changed, 11 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index ea55a28..9e371be 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@
- Openapi SDK for PHP + Openapi SDK for Python -

Openapi® client for PHP

-

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

+

Openapi® client for Python

+

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

-[![Build Status](https://github.com/openapi/openapi-php-sdk/actions/workflows/php.yml/badge.svg)](https://github.com/openapi/openapi-php-sdk/actions/workflows/php.yml) +[![Build Status](https://github.com/openapi/openapi-python-sdk/actions/workflows/python.yml/badge.svg)](https://github.com/openapi/openapi-python-sdk/actions/workflows/python.yml) [![Packagist Version](https://img.shields.io/packagist/v/openapi/openapi-sdk)](https://packagist.org/packages/openapi/openapi-sdk) -[![PHP Version](https://img.shields.io/packagist/php-v/openapi/openapi-sdk)](https://packagist.org/packages/openapi/openapi-sdk) -[![License](https://img.shields.io/github/license/openapi/openapi-php-sdk?v=2)](LICENSE) +[![PyPI Version](https://img.shields.io/packagist/python-v/openapi/openapi-sdk)](https://packagist.org/packages/openapi/openapi-sdk) +[![License](https://img.shields.io/github/license/openapi/openapi-python-sdk?v=2)](LICENSE) [![Downloads](https://img.shields.io/packagist/dt/openapi/openapi-sdk)](https://packagist.org/packages/openapi/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) @@ -17,23 +17,23 @@ ## Overview -A minimal and agnostic PHP SDK for Openapi, inspired by a clean client implementation. This SDK provides only the core HTTP primitives needed to interact with any Openapi service. +A minimal and agnostic Python SDK for Openapi, inspired by a clean client implementation. This SDK provides only the core HTTP primitives needed to interact with any Openapi service. ## Pre-requisites -Before using the Openapi PHP Client, you will need an account at [Openapi](https://console.openapi.com/) and an API key to the sandbox and/or production environment +Before using the Openapi Python Client, you will need an account at [Openapi](https://console.openapi.com/) and an API key to the sandbox and/or production environment ## Features - **Agnostic Design**: No API-specific classes, works with any OpenAPI service -- **Minimal Dependencies**: Only requires PHP 8.0+ and cURL +- **Minimal Dependencies**: Only requires Python 3.8+ and `requests` - **OAuth Support**: Built-in OAuth client for token management - **HTTP Primitives**: GET, POST, PUT, DELETE, PATCH methods - **Clean Interface**: Similar to the Rust SDK design ## What you can do -With the Openapi PHP Client, you can easily interact with a variety of services in the Openapi Marketplace. For example, you can: +With the Openapi Python Client, you can easily interact with a variety of services in the Openapi Marketplace. For example, you can: - 📩 **Send SMS messages** with delivery reports and custom sender IDs - 💸 **Process bills and payments** in real time via API @@ -43,9 +43,6 @@ With the Openapi PHP Client, you can easily interact with a variety of services For a complete list of all available services, check out the [Openapi Marketplace](https://console.openapi.com/) 🌐 - - - # OpenApi IT Python Client This client is used to interact with the API found at [openapi.it](https://openapi.it/) @@ -104,25 +101,6 @@ resp = client.request( resp = oauth_client.delete_token(id=token) ``` -## Contributing - -Contributions are always welcome! - -See `contributing.md` for ways to get started. - -Please adhere to this project's `code of conduct`. - - -## License - -[MIT](https://choosealicense.com/licenses/mit/) - - -## Authors - -- [@maiku1008](https://www.github.com/maiku1008) -- [@openapi-it](https://github.com/openapi-it) - @@ -136,7 +114,7 @@ See [docs/contributing.md](docs/contributing.md) for detailed instructions on ho Meet the project authors: -- L. Paderi ([@lpaderiAltravia](https://www.github.com/lpaderiAltravia)) +- Michael Cuffaro ([@maiku1008](https://www.github.com/maiku1008)) - Openapi Team ([@openapi-it](https://github.com/openapi-it)) ## Partners From c637ed7c12bd42f5595623e7269b6dfa0f358b50 Mon Sep 17 00:00:00 2001 From: francesco Date: Wed, 18 Mar 2026 11:35:25 +0100 Subject: [PATCH 05/13] feat(examples): rewrite examples from Rust to Python --- docs/readme-pypi.md | 0 examples/api_calls.py | 33 +++++++++++++++++++++++++++++++++ examples/token_generation.py | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 docs/readme-pypi.md create mode 100644 examples/api_calls.py create mode 100644 examples/token_generation.py diff --git a/docs/readme-pypi.md b/docs/readme-pypi.md new file mode 100644 index 0000000..e69de29 diff --git a/examples/api_calls.py b/examples/api_calls.py new file mode 100644 index 0000000..990becc --- /dev/null +++ b/examples/api_calls.py @@ -0,0 +1,33 @@ +""" +Step 2 — API Calls +================== +Use a previously generated bearer token to call Openapi endpoints. +Run token_generation.py first, then paste the token below (or pass it via env). + +Usage: + OPENAPI_TOKEN= python examples/api_calls.py +""" + +import os + +from openapi_python_sdk.client import Client + +token = os.environ.get("OPENAPI_TOKEN", "") + +client = Client(token=token) + +# GET request with query params +resp = client.request( + method="GET", + url="https://test.imprese.openapi.it/advance", + params={"denominazione": "altravia", "provincia": "RM", "codice_ateco": "6201"}, +) +print("GET response:", resp) + +# POST request with a JSON payload +resp = client.request( + method="POST", + url="https://test.postontarget.com/fields/country", + payload={"limit": 0, "query": {"country_code": "IT"}}, +) +print("POST response:", resp) diff --git a/examples/token_generation.py b/examples/token_generation.py new file mode 100644 index 0000000..0d29053 --- /dev/null +++ b/examples/token_generation.py @@ -0,0 +1,33 @@ +""" +Step 1 — Token Generation +========================= +Authenticate with your credentials and create a short-lived bearer token +scoped to the API endpoints you need to call. + +Usage: + OPENAPI_USERNAME= OPENAPI_APIKEY= python examples/token_generation.py +""" + +import os + +from openapi_python_sdk.client import OauthClient + +username = os.environ.get("OPENAPI_USERNAME", "") +apikey = os.environ.get("OPENAPI_APIKEY", "") + +oauth = OauthClient(username=username, apikey=apikey, test=True) + +# Create a token valid for 1 hour, scoped to the endpoints you need +resp = oauth.create_token( + scopes=[ + "GET:test.imprese.openapi.it/advance", + "POST:test.postontarget.com/fields/country", + ], + ttl=3600, +) +token = resp["token"] +print(f"Token created: {token}") + +# Revoke the token when you are done +oauth.delete_token(id=token) +print("Token revoked.") From 19a79ae35f556bba6ed75ae116c51e147c7ebc9f Mon Sep 17 00:00:00 2001 From: francesco Date: Wed, 18 Mar 2026 11:35:28 +0100 Subject: [PATCH 06/13] test(client): add unit tests for OauthClient and Client --- tests/__init__.py | 0 tests/test_client.py | 114 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 tests/__init__.py create mode 100644 tests/test_client.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_client.py b/tests/test_client.py new file mode 100644 index 0000000..d9ac4dd --- /dev/null +++ b/tests/test_client.py @@ -0,0 +1,114 @@ +import unittest +from unittest.mock import MagicMock, patch + +from openapi_python_sdk.client import Client, OauthClient + + +class TestOauthClient(unittest.TestCase): + + @patch("openapi_python_sdk.client.httpx.Client") + def test_create_token(self, mock_httpx): + mock_resp = MagicMock() + mock_resp.json.return_value = {"token": "abc123"} + mock_httpx.return_value.post.return_value = mock_resp + + oauth = OauthClient(username="user", apikey="key", test=True) + resp = oauth.create_token(scopes=["GET:test.example.com/api"], ttl=3600) + + self.assertEqual(resp["token"], "abc123") + mock_httpx.return_value.post.assert_called_once() + + @patch("openapi_python_sdk.client.httpx.Client") + def test_delete_token(self, mock_httpx): + mock_resp = MagicMock() + mock_resp.json.return_value = {"success": True} + mock_httpx.return_value.delete.return_value = mock_resp + + oauth = OauthClient(username="user", apikey="key", test=True) + resp = oauth.delete_token(id="abc123") + + self.assertTrue(resp["success"]) + mock_httpx.return_value.delete.assert_called_once() + + @patch("openapi_python_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"]} + mock_httpx.return_value.get.return_value = mock_resp + + oauth = OauthClient(username="user", apikey="key") + resp = oauth.get_scopes() + + self.assertIn("scopes", resp) + + @patch("openapi_python_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") + 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") + def test_auth_header_is_basic(self, mock_httpx): + oauth = OauthClient(username="user", apikey="key") + self.assertTrue(oauth.auth_header.startswith("Basic ")) + + +class TestClient(unittest.TestCase): + + @patch("openapi_python_sdk.client.httpx.Client") + def test_request_get(self, mock_httpx): + mock_resp = MagicMock() + mock_resp.json.return_value = {"data": []} + mock_httpx.return_value.request.return_value = mock_resp + + client = Client(token="abc123") + resp = client.request( + method="GET", + url="https://test.imprese.openapi.it/advance", + params={"denominazione": "altravia"}, + ) + + self.assertEqual(resp, {"data": []}) + mock_httpx.return_value.request.assert_called_once() + + @patch("openapi_python_sdk.client.httpx.Client") + def test_request_post(self, mock_httpx): + mock_resp = MagicMock() + mock_resp.json.return_value = {"result": "ok"} + mock_httpx.return_value.request.return_value = mock_resp + + client = Client(token="abc123") + resp = client.request( + method="POST", + url="https://test.postontarget.com/fields/country", + payload={"limit": 0, "query": {"country_code": "IT"}}, + ) + + self.assertEqual(resp["result"], "ok") + + @patch("openapi_python_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") + def test_defaults_on_empty_request(self, mock_httpx): + mock_resp = MagicMock() + mock_resp.json.return_value = {} + mock_httpx.return_value.request.return_value = mock_resp + + client = Client(token="tok") + resp = client.request() + + mock_httpx.return_value.request.assert_called_once_with( + method="GET", url="", headers=client.headers, json={}, params={} + ) + + +if __name__ == "__main__": + unittest.main() From 3436a9c94131157c7f21732d2f41336084c79a14 Mon Sep 17 00:00:00 2001 From: francesco Date: Wed, 18 Mar 2026 11:35:33 +0100 Subject: [PATCH 07/13] chore(deps): bump version to 0.2.0 and add pytest dev dependency --- pyproject.toml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 649e3b8..873a0b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,15 +1,20 @@ [tool.poetry] -name = "openapi-cli-python" -version = "0.1.0" -description = "" +name = "openapi-python-sdk" +version = "0.2.0" +description = "A minimal Python SDK for the Openapi® API marketplace" authors = ["Michael Cuffaro "] -readme = "README.md" -packages = [{include = "openapi_cli_python"}] +readme = "docs/readme-pypi.md" +packages = [{include = "openapi_python_sdk"}] [tool.poetry.dependencies] python = "^3.10" httpx = "^0.24.0" +[tool.poetry.group.dev.dependencies] +pytest = "^8.0" + +[tool.pytest.ini_options] +testpaths = ["tests"] [build-system] requires = ["poetry-core"] From 3bca4e9f3467c2ee9bcfb71b4a7c32989b85d820 Mon Sep 17 00:00:00 2001 From: francesco Date: Wed, 18 Mar 2026 11:35:38 +0100 Subject: [PATCH 08/13] ci(workflow): add pytest step to python.yml --- .github/workflows/python.yml | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/python.yml diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml new file mode 100644 index 0000000..0c0ef56 --- /dev/null +++ b/.github/workflows/python.yml @@ -0,0 +1,37 @@ +name: Python + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [ "3.10", "3.11", "3.12" ] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install Poetry + uses: snok/install-poetry@v1 + with: + virtualenvs-create: true + virtualenvs-in-project: true + + - name: Install dependencies + run: poetry install --no-interaction + + - name: Test + run: poetry run pytest + + - name: Build + run: poetry build From ee7cef64c0669a15d776d96dfa79fd033b3c73ba Mon Sep 17 00:00:00 2001 From: francesco Date: Wed, 18 Mar 2026 11:35:41 +0100 Subject: [PATCH 09/13] docs(readme): split usage into two steps, add installation and testing sections --- README.md | 73 ++++++++++++++++++------------- docs/readme-pypi.md | 102 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 9e371be..582a63b 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@

Openapi® client for Python

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

-[![Build Status](https://github.com/openapi/openapi-python-sdk/actions/workflows/python.yml/badge.svg)](https://github.com/openapi/openapi-python-sdk/actions/workflows/python.yml) -[![Packagist Version](https://img.shields.io/packagist/v/openapi/openapi-sdk)](https://packagist.org/packages/openapi/openapi-sdk) -[![PyPI Version](https://img.shields.io/packagist/python-v/openapi/openapi-sdk)](https://packagist.org/packages/openapi/openapi-sdk) -[![License](https://img.shields.io/github/license/openapi/openapi-python-sdk?v=2)](LICENSE) -[![Downloads](https://img.shields.io/packagist/dt/openapi/openapi-sdk)](https://packagist.org/packages/openapi/openapi-sdk) +[![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/pypi/pyversions/openapi-python-sdk)](https://pypi.org/project/openapi-python-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/)
[![Linux Foundation Member](https://img.shields.io/badge/Linux%20Foundation-Silver%20Member-003778?logo=linux-foundation&logoColor=white)](https://www.linuxfoundation.org/about/members)
@@ -43,35 +43,27 @@ With the Openapi Python Client, you can easily interact with a variety of servic For a complete list of all available services, check out the [Openapi Marketplace](https://console.openapi.com/) 🌐 -# OpenApi IT Python Client - -This client is used to interact with the API found at [openapi.it](https://openapi.it/) - -## Pre-requisites - -Before using the OpenApi IT Python Client, you will need an account at [openapi.it](https://openapi.it/) and an API key to the sandbox and/or production environment ## Installation -You can install the OpenApi IT Python Client with the following command using go get: - ```bash -pip install openapi-cli-python +pip install openapi-python-sdk ``` - + ## Usage +Interaction with the Openapi platform happens in two distinct steps. + +### Step 1 — Generate a token + +Authenticate with your credentials and obtain a short-lived bearer token scoped to the endpoints you need. ```python -from openapi.client import Client, OauthClient +from openapi_python_sdk.client import OauthClient -# Initialize the oauth client on the sandbox environment -oauth_client = OauthClient( - username="", apikey="", test=True -) +oauth = OauthClient(username="", apikey="", test=True) -# Create a token for a list of scopes -resp = oauth_client.create_token( +resp = oauth.create_token( scopes=[ "GET:test.imprese.openapi.it/advance", "POST:test.postontarget.com/fields/country", @@ -80,25 +72,48 @@ resp = oauth_client.create_token( ) token = resp["token"] -# Initialize the client +# Revoke the token when done +oauth.delete_token(id=token) +``` + +### Step 2 — Call an API endpoint + +Use the token to make authenticated requests to any Openapi service. + +```python +from openapi_python_sdk.client import Client + client = Client(token=token) -# Make a request with params +# GET with query params resp = client.request( method="GET", url="https://test.imprese.openapi.it/advance", params={"denominazione": "altravia", "provincia": "RM", "codice_ateco": "6201"}, ) -# Make a request with a payload +# POST with a JSON payload resp = client.request( method="POST", url="https://test.postontarget.com/fields/country", - payload={"limit": 0, "query": { "country_code": "IT"}} + payload={"limit": 0, "query": {"country_code": "IT"}}, ) +``` + +## Testing + +Install dev dependencies and run the test suite: -# Delete the token -resp = oauth_client.delete_token(id=token) +```bash +pip install pytest +pytest +``` + +Or with Poetry: + +```bash +poetry install +poetry run pytest ``` diff --git a/docs/readme-pypi.md b/docs/readme-pypi.md index e69de29..60c3790 100644 --- a/docs/readme-pypi.md +++ b/docs/readme-pypi.md @@ -0,0 +1,102 @@ +# openapi-python-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. + +## Requirements + +- Python 3.10+ +- An account on [console.openapi.com](https://console.openapi.com/) with a valid API key + +## Installation + +```bash +pip install openapi-python-sdk +``` + +## Usage + +Interaction with the Openapi platform happens in two distinct steps. + +### Step 1 — Generate a token + +```python +from openapi_python_sdk.client import OauthClient + +oauth = OauthClient(username="", apikey="", test=True) + +resp = oauth.create_token( + scopes=[ + "GET:test.imprese.openapi.it/advance", + "POST:test.postontarget.com/fields/country", + ], + ttl=3600, +) +token = resp["token"] + +# Revoke the token when done +oauth.delete_token(id=token) +``` + +### Step 2 — Call an API endpoint + +```python +from openapi_python_sdk.client import Client + +client = Client(token=token) + +# GET with query params +resp = client.request( + method="GET", + url="https://test.imprese.openapi.it/advance", + params={"denominazione": "altravia", "provincia": "RM", "codice_ateco": "6201"}, +) + +# POST with a JSON payload +resp = client.request( + method="POST", + url="https://test.postontarget.com/fields/country", + payload={"limit": 0, "query": {"country_code": "IT"}}, +) +``` + +## Testing + +```bash +pip install pytest +pytest +``` + +## OauthClient API + +| Method | Description | +|---|---| +| `OauthClient(username, apikey, test=False)` | Initialize the OAuth client. Set `test=True` for sandbox. | +| `create_token(scopes, ttl)` | Create a bearer token for the given scopes and TTL (seconds). | +| `get_token(scope)` | Retrieve an existing token by scope. | +| `delete_token(id)` | Revoke a token by ID. | +| `get_scopes(limit=False)` | List available scopes. | +| `get_counters(period, date)` | Retrieve usage counters for a given period and date. | + +## Client API + +| Method | Description | +|---|---| +| `Client(token)` | Initialize the client with a bearer token. | +| `request(method, url, payload, params)` | Execute an HTTP request against any Openapi endpoint. | + +## Links + +- Homepage: [openapi.it](https://openapi.it) +- Console & API keys: [console.openapi.com](https://console.openapi.com/) +- GitHub: [github.com/openapi/openapi-python-sdk](https://github.com/openapi/openapi-python-sdk) +- Issue tracker: [github.com/openapi/openapi-python-sdk/issues](https://github.com/openapi/openapi-python-sdk/issues) + +## License + +MIT — see [LICENSE](https://github.com/openapi/openapi-python-sdk/blob/main/LICENSE) for details. + +## Authors + +- Michael Cuffaro ([@maiku1008](https://github.com/maiku1008)) +- Openapi Team ([@openapi-it](https://github.com/openapi-it)) From 1cbf701342e8bd0297767345f1daa694471d0e65 Mon Sep 17 00:00:00 2001 From: francesco Date: Wed, 18 Mar 2026 11:37:50 +0100 Subject: [PATCH 10/13] docs(readme): enrich installation section with pip, poetry and dependency info --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 582a63b..1970d73 100644 --- a/README.md +++ b/README.md @@ -46,10 +46,21 @@ 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. +Install it with pip: + ```bash pip install openapi-python-sdk ``` +If you are using Poetry: + +```bash +poetry add openapi-python-sdk +``` + +No additional configuration is needed. The only runtime dependency is [`httpx`](https://www.python-httpx.org/). + ## Usage Interaction with the Openapi platform happens in two distinct steps. From c2c5520187b7470226380b3c43d85bb6a8328bb1 Mon Sep 17 00:00:00 2001 From: francesco Date: Wed, 18 Mar 2026 11:37:58 +0100 Subject: [PATCH 11/13] refactor(package): rename package folder from openapi to openapi_python_sdk --- {openapi => openapi_python_sdk}/__init__.py | 0 {openapi => openapi_python_sdk}/client.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {openapi => openapi_python_sdk}/__init__.py (100%) rename {openapi => openapi_python_sdk}/client.py (100%) diff --git a/openapi/__init__.py b/openapi_python_sdk/__init__.py similarity index 100% rename from openapi/__init__.py rename to openapi_python_sdk/__init__.py diff --git a/openapi/client.py b/openapi_python_sdk/client.py similarity index 100% rename from openapi/client.py rename to openapi_python_sdk/client.py From f66759845c66e9bef4d71f98757c3714dd46ee1c Mon Sep 17 00:00:00 2001 From: francesco Date: Wed, 18 Mar 2026 11:38:03 +0100 Subject: [PATCH 12/13] chore(config): add convcommit config and update Makefile and gitignore --- .convcommit | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ .gitignore | 1 + Makefile | 35 +++++++++++++++--------- 3 files changed, 99 insertions(+), 13 deletions(-) create mode 100644 .convcommit diff --git a/.convcommit b/.convcommit new file mode 100644 index 0000000..0eed165 --- /dev/null +++ b/.convcommit @@ -0,0 +1,76 @@ +# convcommit - Conventional Commit message builder +# This file is read by the `convcommit` CLI tool to populate +# the interactive selector menus. +# Commit this file to share the project's commit vocabulary with the team. +# +# FORMAT +# type: — commit type option (e.g. fix, feat, docs) +# scope: — commit scope option +# message: — commit message template +# +# SPECIAL PREFIXES +# ~ — marks the default selection +# _ — enables free-text manual input (press ".") +# [X] — forces key letter X for this entry (e.g. [B]build, [W]wip) +# +# HOW TO USE (interactive) +# Run `convcommit` in a git repo. A menu appears for type, scope, message. +# Press the letter in brackets [A][B]... or [.] for free-text input. +# Stage and push in one shot: +# convcommit -a -p +# +# HOW TO USE (direct flags — scripts, AI agents) +# Bypass the selector entirely with explicit flags: +# convcommit --type fix --scope auth --message "fix null pointer" --push +# convcommit -t feat -s api -m "add endpoint" -a -p +# +# SMART PATTERN — stage specific files and commit in one command +# Use --add instead of nested command substitution. +# Anti-pattern (avoid): +# msg=$(convcommit --type fix --message "fix") && git commit -m "$msg" && git push +# Recommended: +# convcommit --add src/auth.sh --type fix --scope auth --message "fix null pointer" --push +# Stage multiple files: +# convcommit --add src/auth.sh --add tests/auth_test.sh -t test -s auth -m "add tests" -p +# +# HOW TO USE (pipe / non-interactive) +# Pipe selections as lines: one per stage (type, scope, message). +# Use the letter shown in the menu, or "." to trigger free-text input. +# Examples: +# printf "G\n.\nfix null pointer in login\n" | convcommit +# printf "F\n\nadd endpoint\n" | convcommit -a -p +# Capture just the formatted message: +# msg=$(printf "G\n\nfix null pointer\n" | convcommit) +# +# OTHER USEFUL FLAGS +# --reset Regenerate this file with the latest defaults +# --help Show all options +# +# INSTALLATION +# convcommit is a single bash file with no dependencies. +# Install it locally in your project: +# curl -fsSL https://raw.githubusercontent.com/francescobianco/convcommit/refs/heads/main/bin/convcommit \ +# -o bin/convcommit && chmod +x bin/convcommit +# Or system-wide: +# curl -fsSL https://raw.githubusercontent.com/francescobianco/convcommit/refs/heads/main/bin/convcommit \ +# -o /usr/local/bin/convcommit && chmod +x /usr/local/bin/convcommit +type:[B]build +type:~chore +type:[D]docs +type:deps +type:feat +type:fix +type:ci +type:init +type:merge +type:perf +type:refactor +type:revert +type:security +type:style +type:test +type:[W]wip +scope:_ +scope:~ +message:_ +message:~_ diff --git a/.gitignore b/.gitignore index e8642d6..5f6a183 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ share/python-wheels/ *.egg MANIFEST + # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. diff --git a/Makefile b/Makefile index a35e742..d006704 100644 --- a/Makefile +++ b/Makefile @@ -14,14 +14,13 @@ # # # ═══════════════════════════════════════════════════════════════════════ # # # -# Project: openapi-rust-sdk # -# Version: 0.1.0 # +# Project: openapi-python-sdk # # Author: Michael Cuffaro (@maiku1008) # # Copyright: (c) 2025 Openapi®. All rights reserved. # # License: MIT # # Maintainer: Francesco Bianco # # Contact: https://openapi.com/ # -# Repository: https://github.com/openapi/openapi-php-sdk/ # +# Repository: https://github.com/openapi-it/openapi-python-sdk/ # # Documentation: https://console.openapi.com/ # # # # ═══════════════════════════════════════════════════════════════════════ # @@ -35,7 +34,8 @@ ## Variables ## ========= -VERSION := 1.2.1 +export PATH := $(HOME)/.local/bin:$(PATH) +VERSION := $(shell grep '^version' pyproject.toml | head -1 | sed 's/.*"\(.*\)".*/\1/') ## ==================== ## Development Commands @@ -51,13 +51,22 @@ dev-push: ## Release Commands ## ================ -push: - @git add . - @git commit -am "Updated at $$(date)" || true - @git push +.PHONY: setup build publish release -release: push - @git add . - @git commit -m "Update PHP SDK to version ${VERSION}" || echo "No changes to commit" - @git tag -fa "${VERSION}" -m "${VERSION}" - @git push origin --tags -f \ No newline at end of file +setup: + @poetry --version > /dev/null 2>&1 || \ + (echo "Installing Poetry..." && curl -sSL https://install.python-poetry.org | python3 -) + +build: setup + @echo "Building version $(VERSION)..." + @poetry build + +publish: build + @echo "Publishing version $(VERSION) to PyPI..." + @poetry publish + +release: publish + @echo "Tagging release $(VERSION)..." + @git tag -fa "$(VERSION)" -m "Release $(VERSION)" + @git push origin --tags -f + @echo "Released $(VERSION) successfully." \ No newline at end of file From e0c1e8e37d85ebd08bc587d340637375bf5d3bdc Mon Sep 17 00:00:00 2001 From: francesco Date: Wed, 18 Mar 2026 11:41:00 +0100 Subject: [PATCH 13/13] docs(badge): replace pyversions badge with static python >= 3.10 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1970d73..5083a7f 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![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/pypi/pyversions/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/) [![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/)