From 031dec18f98da104adb19b5ec2b49eba3a520632 Mon Sep 17 00:00:00 2001 From: Mazzya Date: Wed, 7 May 2025 17:31:30 +0200 Subject: [PATCH 1/9] fix: assert result fixed for rich list function --- tests/rpc/test_rich_list.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/rpc/test_rich_list.py b/tests/rpc/test_rich_list.py index b61cabf..21505ea 100644 --- a/tests/rpc/test_rich_list.py +++ b/tests/rpc/test_rich_list.py @@ -18,7 +18,8 @@ def test_get_rich_list_success(mock_rich_list_response, sample_rich_list_data, r with patch('requests.get', return_value=mock_rich_list_response) as mock_get: result = rpc_client.get_rich_list(sample_page, sample_page_size) - assert result == sample_rich_list_data + #assert result == sample_rich_list_data + assert result.get('richList', {}) == sample_rich_list_data mock_rich_list_response.raise_for_status.assert_called_once() mock_rich_list_response.json.assert_called_once() mock_get.assert_called_once_with( From 6135566d25b7bcce3aa3ae9917660d4ab631bf8c Mon Sep 17 00:00:00 2001 From: Mazzya Date: Wed, 7 May 2025 17:32:37 +0200 Subject: [PATCH 2/9] chore: dead code removed --- tests/rpc/test_rich_list.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rpc/test_rich_list.py b/tests/rpc/test_rich_list.py index 21505ea..2a1ab16 100644 --- a/tests/rpc/test_rich_list.py +++ b/tests/rpc/test_rich_list.py @@ -18,7 +18,7 @@ def test_get_rich_list_success(mock_rich_list_response, sample_rich_list_data, r with patch('requests.get', return_value=mock_rich_list_response) as mock_get: result = rpc_client.get_rich_list(sample_page, sample_page_size) - #assert result == sample_rich_list_data + assert result.get('richList', {}) == sample_rich_list_data mock_rich_list_response.raise_for_status.assert_called_once() mock_rich_list_response.json.assert_called_once() From 18d72c635f95da927e7f58a65e33e7bdaab6ce47 Mon Sep 17 00:00:00 2001 From: Mazzya Date: Wed, 7 May 2025 17:33:30 +0200 Subject: [PATCH 3/9] feat: add index checking function --- qubipy/utils.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/qubipy/utils.py b/qubipy/utils.py index 6a6036a..8acb83e 100644 --- a/qubipy/utils.py +++ b/qubipy/utils.py @@ -42,6 +42,32 @@ def check_ticks_format(start_tick: int, end_tick: int): if start_tick <= 0 or end_tick <= 0: raise QubiPy_Exceptions(QubiPy_Exceptions.INVALID_START_TICK_AND_END_TICK) + + +def check_index(index): + """ + Validates that the string representation of the input represents + a non-negative integer index (composed only of digits). + + This function handles inputs that might be integers or strings + representing non-negative integers. It converts the input to its + string form and checks if this string is non-empty and contains + only decimal digits. + + Args: + index: The input value to validate. Expected to be a value + whose string representation is a non-empty sequence of digits. + + Raises: + QubiPy_Exceptions.INVALID_INDEX: If the string representation of the + input is empty or contains any + character that is not a decimal digit. + """ + + format_index = str(index) + + if not format_index or not format_index.isdigit(): + raise QubiPy_Exceptions(QubiPy_Exceptions.INVALID_INDEX) def is_tx_bytes_invalid(tx: bytes) -> bool: From f8f0abb29c4e778da9edfda91adc137eec185b2e Mon Sep 17 00:00:00 2001 From: Mazzya Date: Wed, 7 May 2025 17:33:57 +0200 Subject: [PATCH 4/9] feat: add new exceptions --- qubipy/exceptions.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qubipy/exceptions.py b/qubipy/exceptions.py index f942caf..0336423 100644 --- a/qubipy/exceptions.py +++ b/qubipy/exceptions.py @@ -40,3 +40,9 @@ class QubiPy_Exceptions(Exception): INVALID_TX_BYTES = "A bytes-like object is required for broadcasting a transaction" + INVALID_INDEX = "You must enter a valid index." + + INVALID_ASSET_NAME = "You must at least indicate the name of the asset, for example 'MLM'." + + INVALID_IDENTITY_ASSET = "You must enter a valid ID and a valid asset name." + From 3cc471dd9aa9cb8a7f2373342d17b087c4edad64 Mon Sep 17 00:00:00 2001 From: Mazzya Date: Wed, 7 May 2025 17:34:39 +0200 Subject: [PATCH 5/9] feat: add new rpc endpoints --- qubipy/endpoints_rpc.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/qubipy/endpoints_rpc.py b/qubipy/endpoints_rpc.py index 6921f6e..58a5626 100644 --- a/qubipy/endpoints_rpc.py +++ b/qubipy/endpoints_rpc.py @@ -46,4 +46,20 @@ LATEST_STATS = '/latest-stats' -RICH_LIST = '/rich-list' \ No newline at end of file +RICH_LIST = '/rich-list' + +# Testing + +ASSETS_ISSUANCE = '/assets/issuances' + +ASSETS_ISSUANCE_INDEX = '/assets/issuances/{index}' + +ASSETS_OWNERSHIPS = '/assets/ownerships' + +ASSETS_OWNERSHIPS_INDEX = '/assets/ownerships/{index}' + +ASSETS_POSSESSIONS = '/assets/possessions' + +ASSETS_POSSESSIONS_INDEX = '/assets/possessions/{index}' + +ASSETS_OWNERS = '/issuers/{issuer_identity}/assets/{asset_name}/owners' \ No newline at end of file From 4ffc91fee00241d2c3201451672c4652981a02c0 Mon Sep 17 00:00:00 2001 From: Mazzya Date: Wed, 7 May 2025 17:36:03 +0200 Subject: [PATCH 6/9] feat: add new endpoints methods --- qubipy/rpc/rpc_client.py | 343 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 341 insertions(+), 2 deletions(-) diff --git a/qubipy/rpc/rpc_client.py b/qubipy/rpc/rpc_client.py index d61233b..d1323da 100644 --- a/qubipy/rpc/rpc_client.py +++ b/qubipy/rpc/rpc_client.py @@ -655,6 +655,345 @@ def get_rich_list(self, page_1: int | None = None, page_size: int | None = None) response = requests.get(f'{self.rpc_url}{RICH_LIST}', params=payload, headers=HEADERS, timeout=self.timeout) response.raise_for_status() data = response.json() - return data.get('richList', {}) + return data + except requests.exceptions.RequestException as E: + raise QubiPy_Exceptions(f"Failed to retrieve the rich list: {str(E)}") from None + + + def get_assets_issuances(self, issuer_identity: str | None = None, asset_name: str | None = None) -> Dict[str, Any]: + + """ + Retrieves asset issuances from the RPC server. + + This method fetches asset issuances and can filter the results based on an + optional issuer identity and/or an optional asset name. + + Args: + issuer_identity (Optional[str], optional): The identity (wallet ID) of the issuer + to filter the issuances by. Defaults to None, meaning no filtering by issuer. + If provided (not None), the format of the wallet ID is validated using + `is_wallet_id_invalid`. + asset_name (Optional[str], optional): The name of the asset to filter the + issuances by. Defaults to None, meaning no filtering by asset name. + + Returns: + Dict[str, Any]: A dictionary containing the asset issuances data from the API response. + Returns an empty dictionary ({}) if the key 'assets' is missing in the + successful API response body. + + Raises: + QubiPy_Exceptions: If the provided `issuer_identity` is not None and its + format is determined to be invalid by `is_wallet_id_invalid`, or if + there is any issue during the API request execution (e.g., network + error, non-2xx HTTP status code response, or timeout). + """ + + + if issuer_identity and is_wallet_id_invalid(issuer_identity): + raise QubiPy_Exceptions(QubiPy_Exceptions.INVALID_ADDRESS_ID) + + payload = { + 'issuerIdentity': issuer_identity, + 'assetName': asset_name + } + + try: + response = requests.get(f'{self.rpc_url}{ASSETS_ISSUANCE}', params=payload, headers=HEADERS, timeout=self.timeout) + response.raise_for_status() + data = response.json() + return data.get('assets', {}) + except requests.exceptions.RequestException as E: + raise QubiPy_Exceptions(f"Failed to retrieve assets issuances: {str(E)}") from None + + def get_assets_issuances_by_index(self, index: int | None = None) -> Dict[str, Any]: + + """ + Retrieves a specific asset issuance by its index from the RPC server. + + This method fetches the details of a single asset issuance based on its + unique index. A valid index is required. + + Args: + index (int | None): The index of the asset issuance to retrieve. Although + the type hint includes `None` and the default is `None`, the function's + validation (`check_index`) requires a value that converts to a non-empty + string of digits (representing a non-negative integer). Passing `None` + or an invalid format will cause a validation error. + + Returns: + Dict[str, Any]: A dictionary containing the data for the specified asset issuance. + Returns an empty dictionary ({}) if the key 'data' is missing in the + successful API response body. + + Raises: + QubiPy_Exceptions: If the provided `index` is invalid (i.e., fails the + validation performed by `check_index`, which includes if it's `None`), + or if there is any issue during the API request execution (e.g., + network error, non-2xx HTTP status code response from the server, or timeout). + Specifically raises `QubiPy_Exceptions.INVALID_INDEX` if the index validation fails. + """ + + check_index(index) + + endpoint = ASSETS_ISSUANCE_INDEX.format(index = index) + + try: + response = requests.get(f'{self.rpc_url}{endpoint}', headers=HEADERS, timeout=self.timeout) + response.raise_for_status() + data = response.json() + return data.get('data', {}) + except requests.exceptions.RequestException as E: + raise QubiPy_Exceptions(f"Failed to retrieve assets issuances by index: {str(E)}") from None + + def get_ownerships_assets(self, issuer_identity: int | None = None, asset_name: int | None = None, owner_identity: int | None = None, ownership_managing_contract: int | None = None) -> Dict[str, Any]: + + """ + Retrieves asset ownerships from the RPC server based on optional criteria. + + This method can filter ownerships by issuer identity, asset name, owner identity, + and/or ownership managing contract. + + Args: + issuer_identity (int | None, optional): The identity (integer ID) of the issuer to filter by. + Defaults to None, meaning no filtering by issuer. + Note: Based on the name, this might conceptually represent a string identifier expected by the API. + asset_name (int | None, optional): The name (integer ID) of the asset to filter by. + Defaults to None. **This parameter is required by this function's validation** + and must not be falsy (i.e., must not be None and must not be the integer 0). + Note: Based on the name, this might conceptually represent a string name expected by the API. + owner_identity (int | None, optional): The identity (integer ID) of the owner to filter by. + Defaults to None, meaning no filtering by owner. + Note: Based on the name, this might conceptually represent a string identifier expected by the API. + ownership_managing_contract (int | None, optional): The identity (integer ID) of the + ownership managing contract to filter by. Defaults to None, meaning no filtering + by contract. + Note: Based on the name, this might conceptually represent a string identifier expected by the API. + + Returns: + Dict[str, Any]: A dictionary containing the asset ownerships data from the API response. + Returns an empty dictionary ({}) if the key 'assets' is missing in the + successful API response body. + + Raises: + QubiPy_Exceptions: If the `asset_name` provided is falsy (i.e., is `None` or the + integer `0`), raising `QubiPy_Exceptions.INVALID_ASSET_NAME`. Also, if there + is any issue during the API request execution (e.g., network error, non-2xx + HTTP status code response from the server, or timeout). + """ + + if not asset_name: + raise QubiPy_Exceptions(QubiPy_Exceptions.INVALID_ASSET_NAME) + + payload = { + 'issuerIdentity': issuer_identity, + 'assetName': asset_name, + 'ownerIdentity': owner_identity, + 'ownershipManagingContract': ownership_managing_contract + } + + try: + response = requests.get(f'{self.rpc_url}{ASSETS_OWNERSHIPS}', params=payload, headers=HEADERS, timeout=self.timeout) + response.raise_for_status() + data = response.json() + return data.get('assets', {}) + except requests.exceptions.RequestException as E: + raise QubiPy_Exceptions(f"Failed to retrieve the ownerships assets: {str(E)}") from None + + def get_ownerships_assets_by_index(self, index: int | None = None) -> Dict[str, Any]: + + """ + Retrieves a specific asset ownership by its index from the RPC server. + + This method fetches the details of a single asset ownership based on its + unique index. A valid index is required. + + Args: + index (int | None): The index of the asset ownership to retrieve. Although + the type hint includes `None` and the default is `None`, the function's + validation (`check_index`) requires a value that converts to a non-empty + string of digits (representing a non-negative integer). Passing `None` + or an invalid format will cause a validation error. + + Returns: + Dict[str, Any]: A dictionary containing the data for the specified asset ownership. + Returns an empty dictionary ({}) if the key 'data' is missing in the + successful API response body. + + Raises: + QubiPy_Exceptions: If the provided `index` is invalid (fails `check_index` + validation, including if it's None), or if there is an issue during + the API request (e.g., network error, non-2xx HTTP status code, or timeout). + Specifically raises `QubiPy_Exceptions.INVALID_INDEX` for index validation failures. + """ + + check_index(index) + + endpoint = ASSETS_OWNERSHIPS_INDEX.format(index = index) + + try: + response = requests.get(f'{self.rpc_url}{endpoint}', headers=HEADERS, timeout=self.timeout) + response.raise_for_status() + data = response.json() + return data.get('data', {}) + except requests.exceptions.RequestException as E: + raise QubiPy_Exceptions(f"Failed to retrieve assets ownerships by index: {str(E)}") from None + + + def get_assets_possessions(self, issuer_identity: int | None = None, asset_name: int | None = None, owner_identity: int | None = None, possessor_identity: int | None = None, ownership_managing_contract: int | None = None, possession_managing_contrct: int | None = None) -> Dict[str, Any]: + + """ + Retrieves asset possessions from the RPC server based on optional criteria. + + This method fetches asset possessions and can filter the results based on + optional issuer identity, asset name, owner identity, possessor identity, + and managing contracts for ownership and possession. + + Args: + issuer_identity (int | None, optional): The identity (integer ID) of the issuer to filter by. + Defaults to None, meaning no filtering by issuer. + Note: Based on the name and common API patterns, this parameter likely represents a string identifier expected by the API. + asset_name (int | None, optional): The name (integer ID) of the asset to filter by. + Defaults to None. **This parameter is required by this function's validation** + and must not be falsy (i.e., must not be None and must not be the integer 0). + Note: Based on the name and common API patterns, this parameter likely represents a string name expected by the API. + owner_identity (int | None, optional): The identity (integer ID) of the owner to filter by. + Defaults to None, meaning no filtering by owner. + Note: Based on the name and common API patterns, this parameter likely represents a string identifier expected by the API. + possessor_identity (int | None, optional): The identity (integer ID) of the possessor to filter by. + Defaults to None, meaning no filtering by possessor. + Note: Based on the name and common API patterns, this parameter likely represents a string identifier expected by the API. + ownership_managing_contract (int | None, optional): The identity (integer ID) of the ownership managing contract to filter by. + Defaults to None, meaning no filtering by ownership managing contract. + Note: Based on the name and common API patterns, this parameter likely represents a string identifier expected by the API. + possession_managing_contrct (int | None, optional): The identity (integer ID) of the possession managing contract to filter by. + Defaults to None, meaning no filtering by possession managing contract. + Note: Based on the name and common API patterns, this parameter likely represents a string identifier expected by the API. + + Returns: + Dict[str, Any]: A dictionary containing the asset possessions data from the API response. + Returns an empty dictionary ({}) if the key 'assets' is missing in the + successful API response body. + + Raises: + QubiPy_Exceptions: If the `asset_name` provided is falsy (i.e., is `None` or the + integer `0`), raising `QubiPy_Exceptions.INVALID_ASSET_NAME`. Also, if there + is any issue during the API request execution (e.g., network error, non-2xx + HTTP status code response from the server, or timeout). + """ + + if not asset_name: + raise QubiPy_Exceptions(QubiPy_Exceptions.INVALID_ASSET_NAME) + + payload = { + 'issuerIdentity': issuer_identity, + 'assetName': asset_name, + 'ownerIdentity': owner_identity, + 'possessorIdentity': possessor_identity, + 'ownershipManagingContract': ownership_managing_contract, + 'possessionManagingConctract': possession_managing_contrct + } + + try: + response = requests.get(f'{self.rpc_url}{ASSETS_POSSESSIONS}', headers=HEADERS, params=payload, timeout=self.timeout) + response.raise_for_status() + data = response.json() + return data.get('assets', {}) + except requests.exceptions.RequestException as E: + raise QubiPy_Exceptions(f"Failed to retrieve ownerships assets by index: {str(E)}") from None + + def get_assets_possessions_by_index(self, index: int | None = None) -> Dict[str, Any]: + + """ + Retrieves specific asset possessions by their index from the RPC server. + + This method fetches the details of asset possessions based on their + unique index. A valid index is required for the request. + + Args: + index (int | None): The index of the asset possessions to retrieve. Although + the type hint includes `None` and the default value is `None`, the + function's internal validation (`check_index`) requires a value that + converts to a non-empty string consisting only of decimal digits + (representing a non-negative integer). Providing `None` or any + other invalid format will raise a validation error. + + Returns: + Dict[str, Any]: A dictionary containing the entire JSON response body + received from the API for the specified asset possessions. + + Raises: + QubiPy_Exceptions: If the provided `index` is invalid (fails the + validation performed by `check_index`, including if the input is `None`), + or if there is any issue during the API request execution (e.g., a + network error, a non-2xx HTTP status code response from the server, or a timeout). + Specifically raises `QubiPy_Exceptions.INVALID_INDEX` if the index validation fails. + """ + + check_index(index) + + endpoint = ASSETS_POSSESSIONS_INDEX.format(index = index) + + try: + response = requests.get(f'{self.rpc_url}{endpoint}', headers=HEADERS, timeout=self.timeout) + response.raise_for_status() + data = response.json() + return data + except requests.exceptions.RequestException as E: + raise QubiPy_Exceptions(f"Failed to retrieve assets possessions by index: {str(E)}") from None + + def get_assets_owners_per_asset(self, issuer_identity: int | None = None, asset_name: str | None = None, page_1: int | None = None, page_size: int | None = None) -> Dict[str, Any]: + + """ + Retrieves the list of owners for a specific asset from the RPC server. + + This method fetches asset owners, requiring the asset to be identified by + its issuer identity and asset name. Pagination parameters (page number and + page size) are optional and sent as query parameters. + + Args: + issuer_identity (int | None): The identity (integer ID) of the asset's issuer. + Defaults to None. **This parameter is required by this function's validation** + and must not be falsy (i.e., must not be None and must not be the integer 0). + Note: Based on the usage in the endpoint path, this parameter is expected by the API. + asset_name (str | None): The name of the asset. Defaults to None. + **This parameter is required by this function's validation** + and must not be falsy (i.e., must not be None and must not be the empty string ""). + Note: This parameter is used in the endpoint path. + page_1 (int | None, optional): The page number for pagination. Defaults to None. + Validation of this parameter's value or format is not performed within this function. + If not None, it's sent as a query parameter 'page'. + page_size (int | None, optional): The number of entries per page for pagination. Defaults to None. + Validation of this parameter's value or format is not performed within this function. + If not None, it's sent as a query parameter 'pageSize'. + + Returns: + Dict[str, Any]: A dictionary containing the entire JSON response body received + from the API, typically including the list of owners for the specified asset + and potentially pagination metadata. + + Raises: + QubiPy_Exceptions: If `issuer_identity` or `asset_name` are falsy (i.e., fails the + `if not issuer_identity or not asset_name:` check), raising + `QubiPy_Exceptions.INVALID_IDENTITY_ASSET`. Also, if there is any issue during + the API request execution (e.g., network error, non-2xx HTTP status code + response, or timeout). + """ + + if not issuer_identity or not asset_name: + raise QubiPy_Exceptions(QubiPy_Exceptions.INVALID_IDENTITY_ASSET) + + payload = { + 'page': page_1, + 'pageSize': page_size + } + + + endpoint = ASSETS_OWNERS.format(issuer_identity=issuer_identity, asset_name=asset_name) + + try: + response = requests.get(f'{self.rpc_url}{endpoint}', headers=HEADERS, params=payload, timeout=self.timeout) + response.raise_for_status() + data = response.json() + return data except requests.exceptions.RequestException as E: - raise QubiPy_Exceptions(f"Failed to retrieve the rich list: {str(E)}") from None \ No newline at end of file + raise QubiPy_Exceptions(f"Failed to retrieve assets owners per asset: {str(E)}") from None \ No newline at end of file From 0c9e2051fb50dfcdaad6d8da395fe32e75a1ed59 Mon Sep 17 00:00:00 2001 From: Mazzya Date: Wed, 7 May 2025 18:15:26 +0200 Subject: [PATCH 7/9] docs: add changelog for 0.3.0 --- CHANGELOG.md | 15 +++++++++++++++ docs/changelog.md | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 393fa33..2344cd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,19 @@ # Change Log + +## v0.3.0-beta - May 7, 2025 +* Added new endpoints methods : + * get_assets_issuances(): Returns a list of issued assets. + * get_assets_issuances_by_index() : Returns an asset issuance by universe index + * get_ownerships_assets(): Returns a list of asset owners. Asset name and issuer are required. Issuer defaults to zero address. + * get_ownerships_assets_by_index(): Returns an asset ownership by universe index. + * get_assets_possessions(): Returns a list of asset possessors. Asset name and issuer are required. Issuer defaults to zero address. + * get_assets_possessions_by_index(): Returns an asset possession by universe index. + * get_assets_owners_per_asset(): Returns the asset owners per asset +* Added a function to check the input index and validate before making the query. +* Added more information to the response returned by the get_rich_list method, such as epoch, tick and more. +* Added new exceptions to handle new errors. +* Fixed get_rich_list method test. + ## v0.2.6-beta - December 26, 2024 * Added a check function to verify and validate the wallet ID before making a call to the Qubic network * Optimized network calls by preventing invalid requests diff --git a/docs/changelog.md b/docs/changelog.md index 393fa33..2344cd8 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,4 +1,19 @@ # Change Log + +## v0.3.0-beta - May 7, 2025 +* Added new endpoints methods : + * get_assets_issuances(): Returns a list of issued assets. + * get_assets_issuances_by_index() : Returns an asset issuance by universe index + * get_ownerships_assets(): Returns a list of asset owners. Asset name and issuer are required. Issuer defaults to zero address. + * get_ownerships_assets_by_index(): Returns an asset ownership by universe index. + * get_assets_possessions(): Returns a list of asset possessors. Asset name and issuer are required. Issuer defaults to zero address. + * get_assets_possessions_by_index(): Returns an asset possession by universe index. + * get_assets_owners_per_asset(): Returns the asset owners per asset +* Added a function to check the input index and validate before making the query. +* Added more information to the response returned by the get_rich_list method, such as epoch, tick and more. +* Added new exceptions to handle new errors. +* Fixed get_rich_list method test. + ## v0.2.6-beta - December 26, 2024 * Added a check function to verify and validate the wallet ID before making a call to the Qubic network * Optimized network calls by preventing invalid requests From a5af809746684534ba6f93af7f85424f18178c07 Mon Sep 17 00:00:00 2001 From: Mazzya Date: Wed, 7 May 2025 18:25:41 +0200 Subject: [PATCH 8/9] docs: update documentation version --- docs/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index caa6de0..0fe68dc 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,11 +1,11 @@ # Welcome to the **QubiPy** official documentation, a Python Library for the QUBIC RPC API -!!! note "Beta Version: 0.2.6" +!!! note "Beta Version: 0.3.0" QubiPy is currently in beta. While functional, some features might change before the stable release. **QubiPy** is a Python library that provides RPC and Core client functionality. You can interact quickly and easily with the Qubic RPC API using the different methods offered by this library. -![release](https://img.shields.io/badge/release-v0.2.6--beta-blue) +![release](https://img.shields.io/badge/release-v0.3.0--beta-blue) ![python](https://img.shields.io/badge/python-3.10_%7C_3.11_%7C_3.12-blue) ![Python Package](https://github.com/QubiPy-Labs/QubiPy/actions/workflows/python-package.yml/badge.svg) ![Code Quality](https://github.com/QubiPy-Labs/QubiPy/actions/workflows/pylint.yml/badge.svg) From 0ed5561f177e25203d78f3df5a595bd69ead6d44 Mon Sep 17 00:00:00 2001 From: Mazzya Date: Wed, 7 May 2025 18:28:24 +0200 Subject: [PATCH 9/9] docs: update version --- README.md | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7bfdc86..c8c395e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Currently, QubiPy is in a very early development phase, so please take this into Please visit the [Change log](https://github.com/QubiPy-Labs/QubiPy/blob/main/docs/changelog.md) to see all changes. -![release](https://img.shields.io/badge/release-v0.2.6--beta-blue) +![release](https://img.shields.io/badge/release-v0.3.0--beta-blue) ![python](https://img.shields.io/badge/python-3.10_%7C_3.11_%7C_3.12-blue) ![Python Package](https://github.com/QubiPy-Labs/QubiPy/actions/workflows/python-package.yml/badge.svg) ![Code Quality](https://github.com/QubiPy-Labs/QubiPy/actions/workflows/pylint.yml/badge.svg) diff --git a/setup.py b/setup.py index ceef3ad..75c0c0a 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -__version__ = '0.2.6' +__version__ = '0.3.0' with open("README.md", "r", encoding="utf-8") as fh: