From 4336d947beaa1a6033af6db0a7475ea18f08e14e Mon Sep 17 00:00:00 2001 From: hieumt2 Date: Wed, 22 May 2019 21:29:16 +0700 Subject: [PATCH] [AP-478] - enable client overrides, anchors, and receipts (#22) * client-overrides * Update identities.md * Update api_info.md * Update chains.md * Update chains.md * Update api_info.md * Update README.md * Update README.md * client-overrides * client-overrides * Update identities.md * Update chains.md * Update api_info.md * Update README.md * Apply kwargs for achors and receipts client * gitignore updates, fixed formatting issues in docs --- .gitignore | 2 + README.md | 43 +++++++ documentation/api_info.md | 13 +- documentation/chains.md | 92 ++++++++++----- documentation/identities.md | 53 ++++++--- factom_sdk/client/anchors_client.py | 13 +- factom_sdk/client/api_info_client.py | 7 +- factom_sdk/client/chains_client.py | 80 +++++++------ factom_sdk/client/entries_client.py | 111 +++++++++++------- factom_sdk/client/identities_client.py | 27 +++-- factom_sdk/client/receipts_client.py | 8 +- factom_sdk/request_handler/request_handler.py | 50 ++++++-- .../utils/identities/identities_key_util.py | 42 ++++--- factom_sdk/utils/validate_signature_util.py | 10 +- sample_app/simulate_notary.py | 5 +- tests/test_api_info_client.py | 2 +- tests/test_chains_client.py | 62 ++++++---- tests/test_entries_client.py | 71 +++++------ tests/test_identities_client.py | 57 +++++---- tests/test_request_handler.py | 9 ++ tests/test_validate_signature_util.py | 18 +-- 21 files changed, 507 insertions(+), 268 deletions(-) diff --git a/.gitignore b/.gitignore index 4aeba92..b8fa4ec 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ coverage.xml .env .venv env/ +test_env venv/ ENV/ env.bak/ @@ -50,3 +51,4 @@ venv.bak/ cover/ .idea .DS_Store +.vscode diff --git a/README.md b/README.md index 0c67ed6..e4e202f 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,8 @@ certain message that you see in your chain. Now that you have initialized the SDK, you can use the SDK's Methods, which will execute the necessary REST API calls on your behalf. +**Note:** The SDK requires to pass all optional parameters with `**kwargs` added as final arguments. Please refer to [**Methods**](#METHODS) section to get the correct parameter names. + Patterns to utilize the Factom SDK: ```python # Return a JSON chain object as is from the API. @@ -135,6 +137,47 @@ entry = factom_client.chains.entries.get('5dc94c605769d8e9dac1423048f8e5a1182e57 'e0e2b7f7920ce25c20cf98c13ae454566e7cda7bb815b8a9ca568320d7bdeb93') ``` +**Note:** The SDK allows for override values that were set in the instatiation of the SDK on a per-method call basis. To override desired parameters that were set in the instantiated SDK class, you may specify any of the following properties in the calls where these properties apply: + +- `app_id` +- `app_key` +- `base_url` +- `automatic_signing` + +Example: + +```python +# Create a chain with automatic_signing turned off for one call + create_chain_response = factom_client.chains.create( + 'TestOverrides', + external_ids = ['TestOverrides', 'CustomerChain', 'cust123'], + automatic_signing = False + ) + +# Return a JSON chain object as is from the API with new app_id, app_key and base_url. +chain = factom_client.chains.get('5dc94c605769d8e9dac1423048f8e5a1182e575aab6d923207a3a8d15771ad63', + base_url = 'https://ephemeral.api.factom.com/v1', + app_id = '4db6b007', + app_key = 'ec0c88e3c5bb57cd7303d070ad838260' +) + +# Return JSON entries array as is from API with new app_id, app_key and base_url. +entries = factom_client.chains.entries.list('5dc94c605769d8e9dac1423048f8e5a1182e575aab6d923207a3a8d15771ad63', + base_url = 'https://ephemeral.api.factom.com/v1', + app_id = '4db6b007', + app_key = 'ec0c88e3c5bb57cd7303d070ad838260' +) + +# Return a JSON single entry object as is from the API with new app_id, app_key and base_url. +entry = factom_client.chains.entries.get('5dc94c605769d8e9dac1423048f8e5a1182e575aab6d923207a3a8d15771ad63', + 'e0e2b7f7920ce25c20cf98c13ae454566e7cda7bb815b8a9ca568320d7bdeb93', + base_url = 'https://ephemeral.api.factom.com/v1', + app_id = '4db6b007', + app_key = 'ec0c88e3c5bb57cd7303d070ad838260' +) +``` + + License ------- diff --git a/documentation/api_info.md b/documentation/api_info.md index 2a840df..238c519 100644 --- a/documentation/api_info.md +++ b/documentation/api_info.md @@ -9,6 +9,15 @@ Gets general information about the Connect API. ```python factom_client.api_info.get() ``` +**Parameters** + +| **Name** | **Type** | **Description** | **SDK Error Message & Description** | +|--------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------| +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key ` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url ` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | + + **Returns**
**Response:** OK @@ -16,9 +25,9 @@ factom_client.api_info.get() - **links**: object
Links to internal paths of the application. - **links.chains:** string
The link to chain API. ```python -{ +{ 'version':'1.0.17', - 'links':{ + 'links':{ 'chains':'/v1/chains' } } diff --git a/documentation/chains.md b/documentation/chains.md index 9ae21fd..a49b37e 100644 --- a/documentation/chains.md +++ b/documentation/chains.md @@ -29,7 +29,12 @@ factom_client.chains.get('4b9532c79d53ab22b85951b4a5853f81c2682132b3c810a95128c3 | **Name** | **Type** | **Description** | **SDK Error Message & Description** | |------------------------------|----------|------------------------------------------------------------------------------|---------------------------------------------------------------------| | `chain_id` | required | string
The unique identifier created for each chain. | **chain_id is required**
`chain_id` parameter was not provided. | -| `signature_validation` | optional | boolean (`true`/`false`/`custom function`)
Default value is `true`. Indicates whether the SDK automatically validates that the chain was signed based on our signing standard.
`custom function`: allows for validating the chain's signature based on custom logic. | +| `signature_validation` | optional | boolean (`True`/`False`/`custom function`)
Default value is `True`. Indicates whether the SDK automatically validates that the chain was signed based on our signing standard.
`custom function`: allows for validating the chain's signature based on custom logic. | +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | + + **Returns** @@ -50,16 +55,16 @@ factom_client.chains.get('4b9532c79d53ab22b85951b4a5853f81c2682132b3c810a95128c3 - **data.dblock.href:** string
An API link to retrieve all information about this directory block. - **data.created_at:** string
The time at which the chain was created. Sent in [ISO 8601 Format](https://en.wikipedia.org/wiki/ISO_8601). For example: `YYYY-MM-DDThh:mm:ss.ssssssZ`. This will be null if the chain is not at least at the `factom` immutability stage. - **status:** string
The result of signature validation.
-Displays an empty string ("") when `signature_validation` is set to `false`. +Displays an empty string ("") when `signature_validation` is set to `False`.
Or displays a function's result when `signature_validation` is set to `custom function`. -
In case `signature_validation` is set to `true` then one of the following values will be returned based on an automatic comparison of the expected SignedChain structure outlined in our signing standard. +
In case `signature_validation` is set to `True` then one of the following values will be returned based on an automatic comparison of the expected SignedChain structure outlined in our signing standard. - **not_signed/invalid_chain_format:** A chain that was not signed or did not conform to the SignedChain structure. - **invalid_signature:** A chain was created in the proper SignedChain structure, but the signature does not match the attached key. - **retired_height:** A chain that conformed to the SignedChain structure and the signature was verified with the listed key, but that key was retired for the signer identity at a height lower than when this chain reached the `factom` immutability stage. - **key_not_found:** A chain that conformed to the SignedChain structure but the signer public key does not belong to the signer identity chain. - **valid_signature:** A chain that conformed to the SignedChain structure and the signature was verified with the listed key. That key was also active for the signer identity at the height when this chain reached the `factom` immutability stage. - + ```python { 'chain':{ @@ -94,10 +99,10 @@ Displays an empty string ("") when `signature_validation` is set to `false`. Creates a new chain with or without signature: -- When the Factom SDK is initialized, if `automatic_signing` = `true`; in order to create a signed chain, you need to pass: +- When the Factom SDK is initialized, if `automatic_signing` = `True`; in order to create a signed chain, you need to pass: - `signer_chain_id` - `signer_private_key` -- When the Factom SDK is initialized, if `automatic_signing` = `false`, SDK creates an unsigned chain and therefore it does not require these parameters. +- When the Factom SDK is initialized, if `automatic_signing` = `False`, SDK creates an unsigned chain and therefore it does not require these parameters. **Sample** ```python @@ -115,12 +120,16 @@ factom_client.chains.create( | **Name** | **Type** | **Description** | **SDK Error Message & Description** | |---------------------------|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `external_ids` | required
or
optional
| array of strings
Tags that can be used to identify your chain. You can search for records that contain a particular `external_ids` using Connect.
**Note:** Since the Connect API requires each array element to be Base64 encoded, the SDK will do so before making the API request. This parameter is only required for creating an unsigned chain (`automatic_signing` is set to `false`). | **at least 1 external_id is required.**
`external_ids` parameter was not provided when `automatic_signing` was set to `false`.

**external_ids must be an array.**
An invalid `external_ids` format was provided. | +| `external_ids` | required
or
optional
| array of strings
Tags that can be used to identify your chain. You can search for records that contain a particular `external_ids` using Connect.
**Note:** Since the Connect API requires each array element to be Base64 encoded, the SDK will do so before making the API request. This parameter is only required for creating an unsigned chain (`automatic_signing` is set to `False`). | **at least 1 external_id is required.**
`external_ids` parameter was not provided when `automatic_signing` was set to `False`.

**external_ids must be an array.**
An invalid `external_ids` format was provided. | | `content` | required | string
This is the data that will make up the first entry in your new chain. It is customary to use this space to describe the entries that are to follow in the chain.
**Note:** Since the Connect API requires the `content` to be Base64 encoded, the SDK will do so before making the API request. | **content is required.**
`content` parameter was not provided. | | `signer_chain_id` | required
or
optional
| string
The chain id of the signer identity.
**Note:** This parameter is optional for creating an unsigned chain. However, if `signer_private_key` is inputted then `signer_chain_id` must also be inputted. | In case of creating a signed chain:
**signer_chain_id is required.**
`signer_chain_id` parameter was not provided.

In case of creating an unsigned chain:
**signer_chain_id is required when passing a signer_private_key.**
`signer_private_key` parameter was provided but lacking `signer_chain_id` parameter. | | `signer_private_key` | required
or
optional
| base58 string in Idsec format
The private key signer would like to sign with. In fact, private key is used to generate the public key, which is included as an external ID on the created signed entry.
**Note:** This parameter is optional for creating an unsigned chain. However, if `signer_chain_id` is inputted then `signer_private_key` must also be inputted. | In case of creating a signed chain:
**signer_private_key is required.**
`signer_private_key` parameter was not provided.

**signer_private_key is invalid.**
An invalid `signer_private_key` parameter was provided or key’s byte length is not equal to 41.

In case of creating an unsigned chain:
**signer_private_key is required when passing a signer_chain_id.**
`signer_chain_id` parameter was provided but lacking `signer_private_key` parameter.

**signer_private_key is invalid.**
`signer_chain_id` was provided but either an invalid `signer_private_key` parameter was also provided or key’s byte length is not equal to 41. | | `callback_url` | optional | string
The URL where you would like to receive the callback from Connect.
**Note:** If this is not specified, callbacks will not be activated. | **callback_url is an invalid url format.**
An invalid `callback_url` format was provided. | | `callback_stages` | optional | array of strings
The immutability stages you would like to be notified about. This list can include any or all of the three stages: `replicated`, `factom`, and `anchored`. For example, when you would like to trigger the callback from Connect at `replicated` and `factom` stage, you would send them in the format: [‘replicated’, ‘factom’].
**Note:** For this field to matter, the URL must be provided. If callbacks are activated (URL has been specified) and this field is not sent, it will default to `factom` and `anchored`. | **callback_stages must be an array.**
An invalid `callback_stages` format was provided. | +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | +| `automatic_signing` | optional | boolean
Setting this property to false allows user to create an unsigned entry, or implement their own way of signing the entry (it is set to true by default in the SDK class that gets instantiated). | **Returns** @@ -149,11 +158,14 @@ factom_client.chains.list() **Parameters** -| **Name** | **Type** | **Description** | **SDK Error Message & Description** | +| **Name** | **Type** | **Description** | **SDK Error Message & Description** | |-----------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------| -| `limit` | optional | integer
The number of items you would like to return back in each stage. The default value is 15. | **limit must be an integer.**
An invalid `limit` format was provided. | -| `offset` | optional | integer
The offset parameter allows you to select which item you would like to start from when a list is returned from Connect. For example, if you have already seen the first 15 items and you would like the next set, you would send an offset of 15. `offset=0` starts from the first item of the set and is the default position. | **offset must be an integer.**
An invalid `offset` format was provided. | -| `stages` | optional | array of strings
The immutability stages you want to restrict results to. You can choose any from `replicated`, `factom`, and `anchored`. The default value are these three stages: `replicated`, `factom`, and `anchored`.
**Note**: If you would like to search among multiple stages, you would send them in the format: [‘replicated’, ‘factom’]. | **stages must be an array.**
An invalid `stages` format was provided. | +| `limit` | optional | integer
The number of items you would like to return back in each stage. The default value is 15. | **limit must be an integer.**
An invalid `limit` format was provided. | +| `offset` | optional | integer
The offset parameter allows you to select which item you would like to start from when a list is returned from Connect. For example, if you have already seen the first 15 items and you would like the next set, you would send an offset of 15. `offset=0` starts from the first item of the set and is the default position. | **offset must be an integer.**
An invalid `offset` format was provided. | +| `stages` | optional | array of strings
The immutability stages you want to restrict results to. You can choose any from `replicated`, `factom`, and `anchored`. The default value are these three stages: `replicated`, `factom`, and `anchored`.
**Note**: If you would like to search among multiple stages, you would send them in the format: [‘replicated’, ‘factom’]. | **stages must be an array.**
An invalid `stages` format was provided. | +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | **Returns** @@ -197,7 +209,7 @@ factom_client.chains.list() ### search -Finds all of the chains with `external_ids` that match what you entered. +Finds all of the chains with `external_ids` that match what you entered. **Sample** ```python @@ -206,11 +218,14 @@ factom_client.chains.search(["TestFunction", "CustomerChain", "cust123"]) **Parameters** -| **Name** | **Type** | **Description** | **SDK Error Message & Description** | +| **Name** | **Type** | **Description** | **SDK Error Message & Description** | |----------------------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `external_ids` | required | array of strings
A list of external IDs associated with the chains user would like to search by. | **at least 1 external_ids is required.**
`external_ids` parameter was not provided.
**external_ids must be an array.**
An invalid `external_ids` format was provided. | -| `limit` | optional | integer
The number of items you would like to return back in each stage. The default value is 15. | **limit must be an integer.**
An invalid `limit` format was provided. | -| `offset` | optional | integer
The offset parameter allows you to select which item you would like to start from when a list is returned from Connect. For example, if you have already seen the first 15 items and you would like the next set, you would send an offset of 15. `offset=0` starts from the first item of the set and is the default position. | **offset must be an integer.**
An invalid `offset` format was provided. | +| `external_ids` | required | array of strings
A list of external IDs associated with the chains user would like to search by. | **at least 1 external_ids is required.**
`external_ids` parameter was not provided.
**external_ids must be an array.**
An invalid `external_ids` format was provided. | +| `limit` | optional | integer
The number of items you would like to return back in each stage. The default value is 15. | **limit must be an integer.**
An invalid `limit` format was provided. | +| `offset` | optional | integer
The offset parameter allows you to select which item you would like to start from when a list is returned from Connect. For example, if you have already seen the first 15 items and you would like the next set, you would send an offset of 15. `offset=0` starts from the first item of the set and is the default position. | **offset must be an integer.**
An invalid `offset` format was provided. | +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | **Returns** @@ -270,7 +285,10 @@ factom_client.chains.entries.get('c15f9e51781a8a4c520c15fd135e761b922b709217ebea |------------------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------| | `chain_id` | required | string
The chain identifier. | **chain_id is required.**
`chain_id` parameter was not provided. | | `entry_hash` | required | string
The SHA256 hash of the entry. | **entry_hash is required.**
`entry_hash` parameter was not provided. | -| `signature_validation` | optional | boolean (`true`/`false`/`custom function`)
The default value is `true`. Indicates whether the SDK automatically validates that the entry was signed based on our signing standard.
`custom function`: allows for validating the entry's signature based on custom logic.| | +| `signature_validation` | optional | boolean (`True`/`False`/`custom function`)
The default value is `True`. Indicates whether the SDK automatically validates that the entry was signed based on our signing standard.
`custom function`: allows for validating the entry's signature based on custom logic.| | +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | **Returns** @@ -292,9 +310,9 @@ factom_client.chains.entries.get('c15f9e51781a8a4c520c15fd135e761b922b709217ebea - **data.eblock.keymr:** string
The Key Merkle Root for this entry block. - **data.eblock.href:** string
An API link to retrieve all information about this entry block. - **status:** string
The result of signature validation.
-Displays an empty string ("") when `signature_validation` is set to `false`.
+Displays an empty string ("") when `signature_validation` is set to `False`.
Or displays a function's result when `signature_validation` is set to `custom function`.
-In case `signature_validation` is set to `true` then one of the following values will be returned based on an automatic comparison of the expected SignedEntry structure outlined in our signing standard. +In case `signature_validation` is set to `True` then one of the following values will be returned based on an automatic comparison of the expected SignedEntry structure outlined in our signing standard. - **not_signed/invalid_entry_format:** An entry that was not signed or did not conform to the SignedEntry structure. - **invalid_signature:** An entry was created in the proper SignedEntry structure, but the signature does not match the attached key. - **retired_height:** An entry that conformed to the SignedEntry structure and the signature was verified with the listed key, but that key was retired for the signer identity at a height lower than when this entry reached the `factom` immutability stage. @@ -335,11 +353,11 @@ In case `signature_validation` is set to `true` then one of the following values Creates a new entry for the selected chain with or without signature: -- When the Factom SDK is initialized, if `automatic_signing` = `true`; in order to create a signed entry, you need to pass: +- When the Factom SDK is initialized, if `automatic_signing` = `True`; in order to create a signed entry, you need to pass: - `signer_chain_id` - `signer_private_key` - When the Factom SDK is initialized, if `automatic_signing` = - `false`, SDK creates an unsigned entry and therefore it does + `False`, SDK creates an unsigned entry and therefore it does not require these parameters. **Sample** @@ -356,12 +374,16 @@ factom_client.chains.entries.create(chain_id='c15f9e51781a8a4c520c15fd135e761b92 | **Name** | **Type** | **Description** | **SDK Error Message & Description** | |---------------------------|----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `chain_id` | required | string
The chain identifier. | **chain_id is required.**
`chain_id` parameter was not provided.
| -| `external_ids` | required
or
optional | array of strings
Tags that can be used to identify your entry. You can search for records that contain a particular external ID using Connect.
**Note:** Since the Connect API requires each array element to be Base64 encoded, the SDK will do so before making the API request. This parameter is only required for creating an unsigned entry (`automatic_signing` is set to `false`). | **at least 1 external_id is required.**
`external_ids` parameter was not provided when `automatic_signing` is set to `false`.

**external_ids must be an array.**
An invalid `external_ids` format was provided. | +| `external_ids` | required
or
optional | array of strings
Tags that can be used to identify your entry. You can search for records that contain a particular external ID using Connect.
**Note:** Since the Connect API requires each array element to be Base64 encoded, the SDK will do so before making the API request. This parameter is only required for creating an unsigned entry (`automatic_signing` is set to `False`). | **at least 1 external_id is required.**
`external_ids` parameter was not provided when `automatic_signing` is set to `False`.

**external_ids must be an array.**
An invalid `external_ids` format was provided. | | `content` | required | string
This is the data that will be stored directly on the blockchain. Please be sure that no private information is entered here.
**Note:** The value in `content` parameter will be encoded in Base64 format by Connect SDK. | **content is required.**
`content` parameter was not provided. | | `signer_chain_id` | required
or
optional | string
The chain ID of the signer identity.
**Note:** This parameter is optional for creating an unsigned entry. However, if `signer_private_key` is inputted then `signer_chain_id` must also be inputted. | In case of creating a signed entry:
**signer_chain_id is required.**
`signer_chain_id` parameter was not provided.

In case of creating an unsigned entry:
**signer_chain_id is required when passing a signer_private_key.**
`signer_private_key` was provided but lacking `signer_chain_id` parameter. | | `signer_private_key` | required
or
optional | a base58 string in Idsec format
The private key signer would like to sign with. In fact, private key is used to generate the public key, which is included as an external ID on the created signed entry.
**Note:** This parameter is optional for creating an unsigned entry. However, if `signer_chain_id` is inputted then `signer_private_key` must also be inputted. | In case of creating a signed entry:
**signer_private_key is required.**
`signer_private_key` parameter was not provided.

**signer_private_key is invalid.**
An invalid `signer_private_key` parameter was provided or key's byte length is not equal to 41.

In case of creating an unsigned entry:
**signer_private_key is required when passing a signer_chain_id.**
`signer_chain_id` was provided but lacking `signer_private_key` parameter.

**signer_private_key is invalid.**
`signer_chain_id` was provided but an invalid `signer_private_key` parameter was provided or key's byte length is not equal to 41. | | `callback_url` | optional | string
the URL you would like the callbacks to be sent to
**Note:** If this is not specified, callbacks will not be activated. | **callback_url is an invalid url format.**
An invalid `callback_url` format was provided. | | `callback_stages` | optional | array of strings
The immutability stages you would like to be notified about. This list can include any or all of these three stages: `replicated`, `factom`, and `anchored`. For example, when you would like to trigger the callback from Connect from `replicated` and `factom` then you would send them in the format: ['replicated', 'factom'].
**Note:** For this field to matter, the URL must be provided. If callbacks are activated (URL has been specified) and this field is not sent, it will default to `factom` and `anchored`. | **callback_stages must be an array.**
An invalid `callback_stages` format was provided. | +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | +| `automatic_signing` | optional | boolean
Setting this property to false allows user to create an unsigned entry, or implement their own way of signing the entry (it is set to true by default in the SDK class that gets instantiated). | **Returns** @@ -395,6 +417,9 @@ factom_client.chains.entries.list('c15f9e51781a8a4c520c15fd135e761b922b709217ebe | `limit` | optional | integer
The number of items you would like back in each page. The default value is 15. | **limit must ben an integer.**
An invalid `limit` format was provided.
| | `offset` | optional | integer
The offset parameter allows you to select which item you would like to start from when a list is returned from Connect. For example, if you have already seen the first 15 items and you would like the next set, you would send an offset of 15. `offset=0` starts from the first item of the set and is the default position. | **offset must be an integer.**
An invalid `offset` format was provided.| | `stages` | optional | array of strings
The immutability stages you want to restrict results to. You can choose any from `replicated`, `factom`, and `anchored`. The default value are these three stages: `replicated`, `factom` and `anchored`.
**Note:** If you would like to search among multiple stages, you would send them in the format ['replicated', 'factom']. | **stages must be an array.**
An invalid `stages` format was provided. | +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | **Returns** @@ -456,7 +481,10 @@ factom_client.chains.entries.get_first('c15f9e51781a8a4c520c15fd135e761b922b7092 | **Name** | **Type** | **Description** | **SDK Error Message & Description** | |------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------| | `chain_id` | required | string
The chain identifier. | **chain_id is required.**
`chain_id` parameter was not provided.
| -| `signature_validation` | optional | boolean (`true`/`false`/`custom function`)
Default value is `true`.
Indicates whether the SDK automatically validates that the entry was signed based on our signing standard.
`custom function`: allows for validating the entry's signature based on custom logic. | | +| `signature_validation` | optional | boolean (`True`/`False`/`custom function`)
Default value is `True`.
Indicates whether the SDK automatically validates that the entry was signed based on our signing standard.
`custom function`: allows for validating the entry's signature based on custom logic. | +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | **Returns** @@ -479,9 +507,9 @@ factom_client.chains.entries.get_first('c15f9e51781a8a4c520c15fd135e761b922b7092 - **data.eblock.keymr:** string
The Key Merkle Root for this entry block. - **data.eblock.href**: string
An API link to retrieve all information about this entry block. - **status:** string
The result of signature validation.
-Displays an empty string ("") when `signature_validation` is set to `false`.
+Displays an empty string ("") when `signature_validation` is set to `False`.
Or displays a function's result when `signature_validation` is set to `custom function`.
-In case `signature_validation` is set to `true` then one of the following values will be returned based on an automatic comparison of the expected SignedEntry structure outlined in our signing standard. +In case `signature_validation` is set to `True` then one of the following values will be returned based on an automatic comparison of the expected SignedEntry structure outlined in our signing standard. - **not_signed/invalid_entry_format:** An entry that was not signed or did not conform to the SignedEntry structure. - **invalid_signature:** An entry was created in the proper SignedEntry structure, but the signature does not match the attached key. - **retired_height:** An entry that conformed to the SignedEntry structure and the signature was verified with the listed key, but that key was retired for the signer identity at a height lower than when this entry reached the `factom` immutability stage. @@ -534,7 +562,10 @@ factom_client.chains.entries.get_last('c15f9e51781a8a4c520c15fd135e761b922b70921 | **Name** | **Type** | **Description** | **SDK Error Message & Description** | |------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------| | `chain_id` | required | string
The chain identifier. | **chain_id is required.**
`chain_id` parameter was not provided.
| -| `signature_validation` | optional | boolean (`true`/`false`/`custom function`)
Default value is `true`.
Indicates whether the SDK automatically validates that the entry was signed based on our signing standard.
`custom function`: allows for validating the entry's signature based on custom logic. | | +| `signature_validation` | optional | boolean (`True`/`False`/`custom function`)
Default value is `True`.
Indicates whether the SDK automatically validates that the entry was signed based on our signing standard.
`custom function`: allows for validating the entry's signature based on custom logic. | | +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | **Returns** @@ -557,9 +588,9 @@ factom_client.chains.entries.get_last('c15f9e51781a8a4c520c15fd135e761b922b70921 - **data.eblock.keymr:** string
The Key Merkle Root for this entry block. - **data.eblock.href**: string
An API link to retrieve all information about this entry block. - **status:** string
The result of signature validation.
-Displays an empty string ("") when `signature_validation` is set to `false`.
+Displays an empty string ("") when `signature_validation` is set to `False`.
Or displays a function's result when `signature_validation` is set to `custom function`.
-In case `signature_validation` is set to `true` then one of the following values will be returned based on an automatic comparison of the expected SignedEntry structure outlined in our signing standard. +In case `signature_validation` is set to `True` then one of the following values will be returned based on an automatic comparison of the expected SignedEntry structure outlined in our signing standard. - **not_signed/invalid_entry_format:** An entry that was not signed or did not conform to the SignedEntry structure. - **invalid_signature:** An entry was created in the proper SignedEntry structure, but the signature does not match the attached key. - **retired_height:** An entry that conformed to the SignedEntry structure and the signature was verified with the listed key, but that key was retired for the signer identity at a height lower than when this entry reached the `factom` immutability stage. @@ -598,7 +629,7 @@ In case `signature_validation` is set to `true` then one of the following values ``` ##### search -Finds all of the entries with `external_ids` that match what you entered. +Finds all of the entries with `external_ids` that match what you entered. **Sample** ```python @@ -614,6 +645,9 @@ factom_client.chains.entries.search('c15f9e51781a8a4c520c15fd135e761b922b709217e | `external_ids` | required | array of strings
A list of external IDs.
**Note:** Since the Connect API requires each array element to be Base64 encoded, the SDK will do so before making the API request. | **at least 1 external_id is required.**
`external_ids` parameter was not provided.
**external_ids must be an array.**
An invalid `external_ids`parameter was provided. | | `limit` | optional | integer
The number of items you would like to return back in each page. The default value is 15. | **limit must be an integer.**
An invalid `limit` format was provided.
| | `offset` | optional | integer
The offset parameter allows you to select which item you would like to start from when a list is returned from Connect. For example, if you have already seen the first 15 items and you would like the next set, you would send an offset of 15. `offset=0` starts from the first item of the set and is the default position. | **offset must be an integer.**
An invalid `offset` format was provided. | +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | **Returns** diff --git a/documentation/identities.md b/documentation/identities.md index 27f4856..98703d0 100644 --- a/documentation/identities.md +++ b/documentation/identities.md @@ -38,6 +38,10 @@ Creates a new Identity chain. You will need to include a unique names array for | `keys` | optional | array of strings
An array of public key strings in base58 idpub format, ordered from the highest to the lowest priority.
**Note:** `keys` must be in base58 idpub format. | **at least 1 key is required.**
An empty array of strings was provided for `keys` parameter.

**"*invalid key*" key is invalid.**
An invalid key for `keys` parameter was provided. `keys` must be in base58 idpub format.

***"duplicated key"* key is duplicated; keys must be unique.**
A duplicate key for the `keys` parameter was provided.

**keys must be an array.**
An invalid `keys` format was provided.

**calculated bytes of names and keys is <*totalBytes*>. It must be less than 10240, use less/shorter names or less keys.**
Too many `names` or `keys` were provided resulting in calculated bytes being larger than 10kb. | `callback_url` | optional | string
The URL you would like the callbacks to be sent to.
**Note:** If this is not specified, callbacks will not be activated. | **callback_url is an invalid url format.**
An invalid `callback_url` format was provided. | | `callback_stages` | optional | array of strings
The immutability stages you would like to be notified about. This list can include any or all of these three stages: `replicated`, `factom`, and `anchored`. For example: when you would like to trigger the callback from Connect at `replicated` and `factom` stage, you would send them in the format: [‘replicated’, ‘factom’].
**Note:** For this field to matter, the URL must be provided. If callbacks are activated (URL has been specified) and this field is not sent, it will default to `factom` and `anchored`. | **callback_stages must be an array.**
An invalid `callback_stages` format was provided. | +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key ` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url ` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | + **Returns** @@ -46,7 +50,7 @@ Creates a new Identity chain. You will need to include a unique names array for - **entry_hash:** string
The unique identifier of the first entry that has been created in this identity chain. - **stage:** string
The current immutability stage of the identity chain and its first entry. - **key_pairs:** an array of objects
The 3 key pairs generated automatically by Factom SDK. This value is not returned if the public keys are provided when creating this identity. - - **key_pairs[].private_key:** string
The private key in base58 Idsec format. + - **key_pairs[].private_key:** string
The private key in base58 Idsec format. - **key_pairs[].public_key:** string
The public key in base58 Idpub format.
```python @@ -85,6 +89,11 @@ factom_client.identities.get('107c8e488e95b63ca6fe1c409aa22c380b5c7be387d139c1cd | **Name** | **Type** | **Description** | **SDK Error Message & Description** | |--------------------------|----------|-----------------------------------------------------------------------|---------------------------------------------------------------------------------------| | `identity_chain_id` | required | string
The unique identifier for the identity chain being requested. | **identity_chain_id is required.**
`identity_chain_id` parameter was not provided. | +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key ` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url ` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | + + **Returns** @@ -93,7 +102,7 @@ factom_client.identities.get('107c8e488e95b63ca6fe1c409aa22c380b5c7be387d139c1cd - **data.version:** string
The identity chain's schema version. This details the format of this digital identity. For more information about the Factom identity schemas, view the documentation [here](https://docs.harmony.factom.com/docs/factom-signing-standard#section-factom-identity-chains). - **data.stage:** string
The immutability stage that this chain has reached. The identity can be considered active once it (and thus its keys) reaches the `factom` stage. - **data.created_height:** integer
The block height at which this chain was written into the Factom blockchain. This is null if the chain has not reached the `factom` stage. -- **data.chain_id:** string
The unique identifier of this identity chain. +- **data.chain_id:** string
The unique identifier of this identity chain. - **data.names:** array of strings
A unique array of strings that together constitute the identity's name.
**Note:** Since the Connect API Base64 encodes these values for transport, each array element will be decoded for you by the SDK. - **data.all_keys_href:** string
An API link to retrieve the keys for this identity. - **data.active_keys:** array of objects
An array of currently active public identity keys ordered from the highest to the lowest priority. @@ -107,7 +116,7 @@ factom_client.identities.get('107c8e488e95b63ca6fe1c409aa22c380b5c7be387d139c1cd - **data.pending_key.activated_height:** integer
The height at which this key became active for this identity - **data.pending_key.retired_height:** integer
The height at which this key was retired for this identity. This will be null if key is still active. - **data.pending_key.priority:** integer
The level of this key within the hierarchy. A lower number indicates a key that allows a holder to replace higher numbered keys. The master key is priority 0. - - **data.pending_key.entry_hash:** string
The hash of the entry that was made documenting the key replacement. + - **data.pending_key.entry_hash:** string
The hash of the entry that was made documenting the key replacement. @@ -155,7 +164,7 @@ factom_client.identities.get('107c8e488e95b63ca6fe1c409aa22c380b5c7be387d139c1cd ##### list Returns all of the keys that were ever active for this Identity. Results -are paginated. +are paginated. **Sample** ```python @@ -169,6 +178,11 @@ factom_client.identities.keys.list('107c8e488e95b63ca6fe1c409aa22c380b5c7be387d1 | `identity_chain_id` | required | string
The unique identifier of the identity chain whose keys are being requested. | **identity_chain_id is required.**
`identity_chain_id` parameter was not provided. | | | `limit` | optional | integer
The maximum number of keys you would like to be returned. The default value is 15. | **limit must be an integer.**
An invalid `limit` format was provided. | | `offset` | optional | integer
The key index (in number of keys from the first key) to start from in the list of all keys. For example, if you have already received the first 15 keys and you would like the next set, you would send an offset of 15. Default value is 0 which represents the first item. | **offset must be an integer.**
An invalid `offset` format was provided. | +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key ` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url ` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | + + **Returns** @@ -178,8 +192,8 @@ factom_client.identities.keys.list('107c8e488e95b63ca6fe1c409aa22c380b5c7be387d1 - **data[].activated_height:** integer
The height at which this key became active for this identity. - **data[].retired_height:** integer
The height at which this key was retired for this identity. The value will be null if the key is still active. - **data[].priority:** integer
-The level of this key within the hierarchy. A lower number indicates a key that allows a holder
-to replace higher numbered keys. The master key is priority 0. +The level of this key within the hierarchy. A lower number indicates a key that allows a holder
+to replace higher numbered keys. The master key is priority 0. - **data[].entry_hash:** string
The entry hash of the entry where this key was activated. @@ -225,7 +239,7 @@ applicable. **Sample** ```python -factom_client.identities.keys.get('107c8e488e95b63ca6fe1c409aa22c380b5c7be387d139c1cd0afaf608d1ae42', +factom_client.identities.keys.get('107c8e488e95b63ca6fe1c409aa22c380b5c7be387d139c1cd0afaf608d1ae42', 'idpub1zbpmSTnvErRkzoXus1hBmHSSFxvagqD3nZiMyna4JmnSnUDwF') ``` @@ -235,6 +249,11 @@ factom_client.identities.keys.get('107c8e488e95b63ca6fe1c409aa22c380b5c7be387d13 |--------------------------|----------|---------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------| | `identity_chain_id` | required | string
The unique identifier for the Identity that the key belongs to. | **identity_chain_id is required.**
`identity_chain_d` parameter was not provided. | | `key` | required | string
The public key string to get information, which must be in base58 idpub format. | **key is required.**
`key` parameter was not provided.

**key is invalid.**
An invalid `key` format was provided. | +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key ` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url ` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | + + **Returns** @@ -243,7 +262,7 @@ factom_client.identities.keys.get('107c8e488e95b63ca6fe1c409aa22c380b5c7be387d13 - **data.key:** string
The public key string in base58 idpub format. - **data.activated_height:** integer
The height at which this key became active for this identity. - **data.retired_height:** integer
The height at which this key was retired for this identity. The value can be null if key is still active. - - **data.priority:** integer
The level of this key within the hierarchy. The master key is priority 0. + - **data.priority:** integer
The level of this key within the hierarchy. The master key is priority 0. - **data.entry_hash:** string
The entry hash of the entry where this key was activated. ```python @@ -259,7 +278,7 @@ factom_client.identities.keys.get('107c8e488e95b63ca6fe1c409aa22c380b5c7be387d13 ``` ##### replace -Creates an entry in the Identity Chain for a key replacement, which means the old key will be deactivated (referred to as a “retired” key) and the new key will be activated. +Creates an entry in the Identity Chain for a key replacement, which means the old key will be deactivated (referred to as a “retired” key) and the new key will be activated. To do this, a user must send the key to be replaced (`old_public_key`), a signature authorizing the replacement and the public key that can be used to validate this signature. The signing key must be of an equal or higher level than the key that is being replaced. @@ -282,19 +301,23 @@ This method will automatically generate a new key pair for you and return it. Op | `signer_private_key` | required | base58 string in Idsec format
The private key to use to create the signature, which must be the same or higher priority than the public key to be replaced. | **signer_private_key is required.**
`signer_private_key` parameter was not provided.

**signer_private_key is invalid.**
An invalid `signer_private_key` parameter was provided or key’s byte length is not equal to 41. | | `callback_url` | optional | string
The URL you would like the callbacks to be sent to.
**Note:** If this is not specified, callbacks will not be activated. | **callback_url is an invalid url format.**
An invalid `callback_url` format was provided. | | `callback_stages` | optional | array of strings
The immutability stages you'd like to be notified about. This list can include any or all of these three stages: `replicated`, `factom`, and `anchored`. For example: when you would like to trigger the callback from Connect from `replicated` and `factom` then you should send them in the format: [‘replicated’, ‘factom’].
**Note:** For this field to matter, the URL must be provided. If callbacks are activated (URL has been specified) and this field is not sent, it will default to `factom` and `anchored`. | **callback_stages must be an array.**
An invalid `callback_stages` format was provided. | +| `app_id` | optional | string
This is the override parameter that allows user to specify a different API Application ID (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `app_key ` | optional | string
This is the override parameter that allows user to specify a different API Application Key (which you can see by clicking on any of the applications in the application list that you see upon logging into https://account.factom.com). | +| `base_url ` | optional | string
This is the override parameter that allows user to specify a different API Base URL for your application (which you can see by clicking on any of the applications in the application list the you see upon logging into https://account.factom.com). | + **Returns** **Response:** OK - **entry_hash:** string
The entry hash that will point to the key replacement entry on the blockchain. - **stage:** string
The current immutability stage of the new entry. -- **key_pair:** object
The key pair generated automatically by the Factom SDK. This value will not be returned if the new public key is provided when calling this method. - - **key_pair.private_key:** string
- The private key in base58 Idsec format. - - **key_pair.public_key:** string
-The public key in base58 Idpub format. +- **key_pair:** object
The key pair generated automatically by the Factom SDK. This value will not be returned if the new public key is provided when calling this method. + - **key_pair.private_key:** string
+ The private key in base58 Idsec format. + - **key_pair.public_key:** string
+The public key in base58 Idpub format. + - ```python { 'stage':'replicated', diff --git a/factom_sdk/client/anchors_client.py b/factom_sdk/client/anchors_client.py index 0856e7c..5973391 100644 --- a/factom_sdk/client/anchors_client.py +++ b/factom_sdk/client/anchors_client.py @@ -6,7 +6,7 @@ class AnchorsClient: def __init__(self, base_url: str, app_id: str, app_key: str): self.request_handler = RequestHandler(base_url, app_id, app_key) - def get(self, object_hash: str = None, height: int = None): + def get(self, **kwargs): """Gets the anchors for a specific entry or directory block from Connect. Args: @@ -16,11 +16,18 @@ def get(self, object_hash: str = None, height: int = None): Returns: Anchors object. """ + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") + object_hash = kwargs.get("object_hash") + height = kwargs.get("height") if object_hash is None: assert height is not None, "either object_hash or height must not be None" assert isinstance(height, int) and height > 0, "height must be a positive integer" - return self.request_handler.get("/".join([factom_sdk.utils.consts.ANCHORS_URL, str(height)])) + return self.request_handler.get("/".join([factom_sdk.utils.consts.ANCHORS_URL, str(height)]), + base_url=base_url, app_id=app_id, app_key=app_key) else: assert isinstance(object_hash, str) and len(object_hash) == 64, "object_hash must be a string of length 64" assert height is None, "object_hash provided, height must be None" - return self.request_handler.get("/".join([factom_sdk.utils.consts.ANCHORS_URL, object_hash])) + return self.request_handler.get("/".join([factom_sdk.utils.consts.ANCHORS_URL, object_hash]), + base_url=base_url, app_id=app_id, app_key=app_key) diff --git a/factom_sdk/client/api_info_client.py b/factom_sdk/client/api_info_client.py index 51776c7..9737ee1 100644 --- a/factom_sdk/client/api_info_client.py +++ b/factom_sdk/client/api_info_client.py @@ -5,10 +5,13 @@ class ApiInfoClient: def __init__(self, base_url: str, app_id: str, app_key: str): self.request_handler = RequestHandler(base_url, app_id, app_key) - def get(self): + def get(self, **kwargs): """Gets general information about the Connect API. Returns: API Info object. """ - return self.request_handler.get() + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") + return self.request_handler.get(base_url=base_url, app_id=app_id, app_key=app_key) diff --git a/factom_sdk/client/chains_client.py b/factom_sdk/client/chains_client.py index 59072a8..fff799f 100644 --- a/factom_sdk/client/chains_client.py +++ b/factom_sdk/client/chains_client.py @@ -17,25 +17,32 @@ def __init__(self, base_url: str, app_id: str, app_key: str, automatic_signing: self.automatic_signing = automatic_signing self.entries = EntriesClient(base_url, app_id, app_key, automatic_signing) - def get(self, chain_id: str, signature_validation=None): + def get(self, chain_id: str, **kwargs): """Gets information about a specific chain from Connect. Args: chain_id (str): The unique identifier created for each chain. - signature_validation (bool | custom function) Returns: Chain object. """ + signature_validation = kwargs.get("signature_validation", None) + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") if not chain_id: raise Exception("chain_id is required.") - response = self.request_handler.get("/".join([factom_sdk.utils.consts.CHAINS_URL, chain_id])) + response = self.request_handler.get("/".join([factom_sdk.utils.consts.CHAINS_URL, chain_id]), + base_url=base_url, app_id=app_id, app_key=app_key) if not callable(signature_validation) and not isinstance(signature_validation, bool): signature_validation = True if signature_validation and isinstance(signature_validation, bool): return { "chain": response, - "status": ValidateSignatureUtil.validate_signature(response, True, self.request_handler) + "status": ValidateSignatureUtil.validate_signature(response, + validate_for_chain=True, + request_handler=self.request_handler, + base_url=base_url, app_id=app_id, app_key=app_key) } elif callable(signature_validation): return { @@ -44,29 +51,28 @@ def get(self, chain_id: str, signature_validation=None): } return response - def create(self, content: str, external_ids: list = None, signer_private_key: str = "", - signer_chain_id: str = "", callback_url: str = "", callback_stages: list = None): + def create(self, content: str, **kwargs): """Creates a new chain Args: content (str): This is the data that will make up the first entry in your new chain. - external_ids (:obj:`list`, optional): Tags that can be used to identify your chain. - signer_private_key (:obj:`str`, optional): base58 string in Idsec format. This parameter is optional for - creating an unsigned chain. - signer_chain_id (:obj:`str`, optional): The chain id of the signer identity. This parameter is optional for - creating an unsigned chain. - callback_url (:obj:`str`, optional): The URL where you would like to receive the callback from Connect. - callback_stages (:obj:`list`, optional): The immutability stages you would like to be notified about. - This list can include any or all of the three stages: `replicated`, `factom`, and `anchored`. Returns: Chain created info object. """ - if callback_stages is None: - callback_stages = [] - if external_ids is None: - external_ids = [] - if self.automatic_signing: + external_ids = kwargs.get("external_ids", []) + signer_private_key = kwargs.get("signer_private_key", "") + signer_chain_id = kwargs.get("signer_chain_id", "") + callback_url = kwargs.get("callback_url", "") + callback_stages = kwargs.get("callback_stages", []) + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") + automatic_signing = kwargs.get("automatic_signing", self.automatic_signing) + if not isinstance(automatic_signing, bool): + automatic_signing = self.automatic_signing + + if automatic_signing: if not isinstance(external_ids, list): raise Exception("external_ids must be an array.") if not signer_private_key: @@ -93,7 +99,7 @@ def create(self, content: str, external_ids: list = None, signer_private_key: st if not isinstance(callback_stages, list): raise Exception("callback_stages must be an array.") ids_base64 = [] - if self.automatic_signing: + if automatic_signing: time_stamp = Utils.to_military_timezone_str(datetime.datetime.now(datetime.timezone.utc)) message = signer_chain_id + content + time_stamp signature = KeyCommon.sign_content(signer_private_key, message) @@ -114,23 +120,24 @@ def create(self, content: str, external_ids: list = None, signer_private_key: st data["callback_url"] = callback_url if callback_stages: data["callback_stages"] = callback_stages - return self.request_handler.post(factom_sdk.utils.consts.CHAINS_URL, data) + return self.request_handler.post(factom_sdk.utils.consts.CHAINS_URL, + data=data, base_url=base_url, app_id=app_id, app_key=app_key) - def list(self, limit: int = -1, offset: int = -1, stages: list = None): + def list(self, **kwargs): """Gets all of the chains on Factom. Args: - limit (:obj:`int`, optional): The number of items you would like to return back in each stage. - offset (:obj:`int`, optional): The offset parameter allows you to select which item you would like to start - from when a list is returned from Connect. - stages (:obj:`list`, optional): The immutability stages you want to restrict results to. - You can choose any from `replicated`, `factom`, and `anchored`. Returns: List chains object. """ - if stages is None: - stages = [] + limit = kwargs.get("limit", -1) + offset = kwargs.get("offset", -1) + stages = kwargs.get("stages", []) + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") + data = {} if not isinstance(limit, int): raise Exception("limit must be an integer.") @@ -144,20 +151,23 @@ def list(self, limit: int = -1, offset: int = -1, stages: list = None): raise Exception("stages must be an array.") if stages: data["stages"] = ",".join(stages) - return self.request_handler.get(factom_sdk.utils.consts.CHAINS_URL, data) + return self.request_handler.get(factom_sdk.utils.consts.CHAINS_URL, + params=data, base_url=base_url, app_id=app_id, app_key=app_key) - def search(self, external_ids: list, limit: int = -1, offset: int = -1): + def search(self, external_ids: list, **kwargs): """Finds all of the chains with `external_ids` that match what you entered. Args: external_ids (list): A list of external IDs associated with the chains user would like to search by. - limit (:obj:`int`, optional): The number of items you would like to return back in each stage. - offset (:obj:`int`, optional): The offset parameter allows you to select which item you would like to start - from when a list is returned from Connect. Returns: List chains object. """ + limit = kwargs.get("limit", -1) + offset = kwargs.get("offset", -1) + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") if not external_ids: raise Exception("at least 1 external_id is required.") if not isinstance(external_ids, list): @@ -176,4 +186,4 @@ def search(self, external_ids: list, limit: int = -1, offset: int = -1): url += "?offset=" + str(offset) ids_base64 = [CommonUtil.base64_encode(val) for val in external_ids] data = {"external_ids": ids_base64} - return self.request_handler.post(url, data) + return self.request_handler.post(url, data=data, base_url=base_url, app_id=app_id, app_key=app_key) diff --git a/factom_sdk/client/entries_client.py b/factom_sdk/client/entries_client.py index f29e97a..e11b1a0 100644 --- a/factom_sdk/client/entries_client.py +++ b/factom_sdk/client/entries_client.py @@ -15,29 +15,36 @@ def __init__(self, base_url: str, app_id: str, app_key: str, automatic_signing: self.request_handler = RequestHandler(base_url, app_id, app_key) self.automatic_signing = automatic_signing - def get(self, chain_id: str, entry_hash: str, signature_validation=None): + def get(self, chain_id: str, entry_hash: str, **kwargs): """Gets information about a specific entry on Connect. Args: chain_id (str): The chain identifier. entry_hash (str): The SHA256 hash of the entry. - signature_validation (bool | custom function) Returns: Entry object. """ + signature_validation = kwargs.get("signature_validation", None) + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") if not chain_id: raise Exception("chain_id is required.") if not entry_hash: raise Exception("entry_hash is required.") response = self.request_handler.get("/".join([factom_sdk.utils.consts.CHAINS_URL, chain_id, - factom_sdk.utils.consts.ENTRIES_URL, entry_hash])) + factom_sdk.utils.consts.ENTRIES_URL, entry_hash]), + base_url=base_url, app_id=app_id, app_key=app_key) if not callable(signature_validation) and not isinstance(signature_validation, bool): signature_validation = True if signature_validation and isinstance(signature_validation, bool): return { "entry": response, - "status": ValidateSignatureUtil.validate_signature(response, False, self.request_handler) + "status": ValidateSignatureUtil.validate_signature(response, + validate_for_chain=False, + request_handler=self.request_handler, + base_url=base_url, app_id=app_id, app_key=app_key) } elif callable(signature_validation): return { @@ -46,33 +53,31 @@ def get(self, chain_id: str, entry_hash: str, signature_validation=None): } return response - def create(self, chain_id: str, content: str, external_ids: list = None, - signer_private_key: str = "", signer_chain_id: str = "", callback_url: str = "", - callback_stages: list = None): + def create(self, chain_id: str, content: str, **kwargs): """Creates a new entry for the selected chain. Args: chain_id (str): The chain identifier. content (str): This is the data that will be stored directly on the blockchain. - external_ids (:obj:`list`, optional): Tags that can be used to identify your entry. - signer_private_key (:obj:`str`, optional): base58 string in Idsec format. This parameter is optional for - creating an unsigned entry. - signer_chain_id (:obj:`str`, optional): The chain id of the signer identity. This parameter is optional for - creating an unsigned entry. - callback_url (:obj:`str`, optional): The URL where you would like to receive the callback from Connect. - callback_stages (:obj:`list`, optional): The immutability stages you would like to be notified about. - This list can include any or all of the three stages: `replicated`, `factom`, and `anchored`. Returns: Entry created object. """ - if callback_stages is None: - callback_stages = [] - if external_ids is None: - external_ids = [] + external_ids = kwargs.get("external_ids", []) + signer_private_key = kwargs.get("signer_private_key", "") + signer_chain_id = kwargs.get("signer_chain_id", "") + callback_url = kwargs.get("callback_url", "") + callback_stages = kwargs.get("callback_stages", []) + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") + automatic_signing = kwargs.get("automatic_signing", self.automatic_signing) + if not isinstance(automatic_signing, bool): + automatic_signing = self.automatic_signing + if not chain_id: raise Exception("chain_id is required.") - if self.automatic_signing: + if automatic_signing: if not isinstance(external_ids, list): raise Exception("external_ids must be an array.") if not signer_private_key: @@ -99,7 +104,7 @@ def create(self, chain_id: str, content: str, external_ids: list = None, if not isinstance(callback_stages, list): raise Exception("callback_stages must be an array.") ids_base64 = [] - if self.automatic_signing: + if automatic_signing: time_stamp = Utils.to_military_timezone_str(datetime.datetime.now(datetime.timezone.utc)) message = signer_chain_id + content + time_stamp signature = KeyCommon.sign_content(signer_private_key, message) @@ -121,24 +126,24 @@ def create(self, chain_id: str, content: str, external_ids: list = None, if callback_stages: data["callback_stages"] = callback_stages return self.request_handler.post("/".join([factom_sdk.utils.consts.CHAINS_URL, chain_id, - factom_sdk.utils.consts.ENTRIES_URL]), data) + factom_sdk.utils.consts.ENTRIES_URL]), + data=data, base_url=base_url, app_id=app_id, app_key=app_key) - def list(self, chain_id: str, limit: int = -1, offset: int = -1, stages: list = None): + def list(self, chain_id: str, **kwargs): """Gets list of all entries contained on a specified chain. Args: chain_id (str): The chain identifier. - limit (:obj:`int`, optional): The number of items you would like to return back in each stage. - offset (:obj:`int`, optional): The offset parameter allows you to select which item you would like to start - from when a list is returned from Connect. - stages (:obj:`list`, optional): The immutability stages you want to restrict results to. - You can choose any from `replicated`, `factom`, and `anchored`. Returns: List entry object. """ - if stages is None: - stages = [] + limit = kwargs.get("limit", -1) + offset = kwargs.get("offset", -1) + stages = kwargs.get("stages", []) + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") if not chain_id: raise Exception("chain_id is required.") data = {} @@ -155,29 +160,38 @@ def list(self, chain_id: str, limit: int = -1, offset: int = -1, stages: list = if stages: data["stages"] = ",".join(stages) return self.request_handler.get("/".join([factom_sdk.utils.consts.CHAINS_URL, chain_id, - factom_sdk.utils.consts.ENTRIES_URL]), data) + factom_sdk.utils.consts.ENTRIES_URL]), + params=data, + base_url=base_url, app_id=app_id, app_key=app_key) - def get_first(self, chain_id: str, signature_validation=None): + def get_first(self, chain_id: str, **kwargs): """Retrieves the first entry that has been saved to this chain. Args: chain_id (str): The chain identifier. - signature_validation (bool | custom function) Returns: Entry object. """ + signature_validation = kwargs.get("signature_validation", None) + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") if not chain_id: raise Exception("chain_id is required.") response = self.request_handler.get("/".join([factom_sdk.utils.consts.CHAINS_URL, chain_id, factom_sdk.utils.consts.ENTRIES_URL, - factom_sdk.utils.consts.FIRST_URL])) + factom_sdk.utils.consts.FIRST_URL]), + base_url=base_url, app_id=app_id, app_key=app_key) if not callable(signature_validation) and not isinstance(signature_validation, bool): signature_validation = True if signature_validation and isinstance(signature_validation, bool): return { "entry": response, - "status": ValidateSignatureUtil.validate_signature(response, False, self.request_handler) + "status": ValidateSignatureUtil.validate_signature(response, + validate_for_chain=False, + request_handler=self.request_handler, + base_url=base_url, app_id=app_id, app_key=app_key) } elif callable(signature_validation): return { @@ -186,27 +200,34 @@ def get_first(self, chain_id: str, signature_validation=None): } return response - def get_last(self, chain_id: str, signature_validation=None): + def get_last(self, chain_id: str, **kwargs): """Gets the last entry that has been saved to this chain. Args: chain_id (str): The chain identifier. - signature_validation (bool | custom function) Returns: Entry object. """ + signature_validation = kwargs.get("signature_validation", None) + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") if not chain_id: raise Exception("chain_id is required.") response = self.request_handler.get("/".join([factom_sdk.utils.consts.CHAINS_URL, chain_id, factom_sdk.utils.consts.ENTRIES_URL, - factom_sdk.utils.consts.LAST_URL])) + factom_sdk.utils.consts.LAST_URL]), + base_url=base_url, app_id=app_id, app_key=app_key) if not callable(signature_validation) and not isinstance(signature_validation, bool): signature_validation = True if signature_validation and isinstance(signature_validation, bool): return { "entry": response, - "status": ValidateSignatureUtil.validate_signature(response, False, self.request_handler) + "status": ValidateSignatureUtil.validate_signature(response, + validate_for_chain=False, + request_handler=self.request_handler, + base_url=base_url, app_id=app_id, app_key=app_key) } elif callable(signature_validation): return { @@ -215,19 +236,21 @@ def get_last(self, chain_id: str, signature_validation=None): } return response - def search(self, chain_id: str, external_ids: list, limit: int = -1, offset: int = -1): + def search(self, chain_id: str, external_ids: list, **kwargs): """Finds all of the entries with `external_ids` that match what you entered. Args: chain_id (str): The chain identifier. external_ids (list): A list of external IDs. - limit (:obj:`int`, optional): The number of items you would like to return back in each stage. - offset (:obj:`int`, optional): The offset parameter allows you to select which item you would like to start - from when a list is returned from Connect. Returns: List entry object. """ + limit = kwargs.get("limit", -1) + offset = kwargs.get("offset", -1) + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") if not chain_id: raise Exception("chain_id is required.") if not external_ids: @@ -249,4 +272,4 @@ def search(self, chain_id: str, external_ids: list, limit: int = -1, offset: int url += "?offset=" + str(offset) ids_base64 = [CommonUtil.base64_encode(val) for val in external_ids] data = {"external_ids": ids_base64} - return self.request_handler.post(url, data) + return self.request_handler.post(url, data=data, base_url=base_url, app_id=app_id, app_key=app_key) diff --git a/factom_sdk/client/identities_client.py b/factom_sdk/client/identities_client.py index ed660dc..aee8284 100644 --- a/factom_sdk/client/identities_client.py +++ b/factom_sdk/client/identities_client.py @@ -11,22 +11,21 @@ def __init__(self, base_url: str, app_id: str, app_key: str): self.request_handler = RequestHandler(base_url, app_id, app_key) self.keys = IdentitiesKeyUtil(base_url, app_id, app_key) - def create(self, names: list, keys: list = None, callback_url: str = "", callback_stages: list = None): + def create(self, names: list, **kwargs): """Creates a new Identity chain. Args: names (list): The names array for your identity must be unique. - keys (:obj:`list`, optional): An array of public key strings in base58 idpub format, ordered from the - highest to the lowest priority. - callback_url (:obj:`str`, optional): The URL where you would like to receive the callback from Connect. - callback_stages (:obj:`list`, optional): The immutability stages you would like to be notified about. - This list can include any or all of the three stages: `replicated`, `factom`, and `anchored`. Returns: Identity chain created object. """ - if callback_stages is None: - callback_stages = [] + keys = kwargs.get("keys", None) + callback_url = kwargs.get("callback_url", "") + callback_stages = kwargs.get("callback_stages", []) + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") if not names: raise Exception("at least 1 name is required.") if not isinstance(names, list): @@ -77,12 +76,14 @@ def create(self, names: list, keys: list = None, callback_url: str = "", callbac data["callback_url"] = callback_url if callback_stages: data["callback_stages"] = callback_stages - response = self.request_handler.post(factom_sdk.utils.consts.IDENTITY_URL, data) + response = self.request_handler.post(factom_sdk.utils.consts.IDENTITY_URL, + data=data, + base_url=base_url, app_id=app_id, app_key=app_key) if keys is None: response["key_pairs"] = key_pairs return response - def get(self, identity_chain_id: str): + def get(self, identity_chain_id: str, **kwargs): """Gets a summary of the identity chain's current state. Args: @@ -91,6 +92,10 @@ def get(self, identity_chain_id: str): Returns: Identity chain object. """ + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") if not identity_chain_id: raise Exception("identity_chain_id is required.") - return self.request_handler.get("/".join([factom_sdk.utils.consts.IDENTITY_URL, identity_chain_id])) + return self.request_handler.get("/".join([factom_sdk.utils.consts.IDENTITY_URL, identity_chain_id]), + base_url=base_url, app_id=app_id, app_key=app_key) diff --git a/factom_sdk/client/receipts_client.py b/factom_sdk/client/receipts_client.py index cdf57cd..ded711d 100644 --- a/factom_sdk/client/receipts_client.py +++ b/factom_sdk/client/receipts_client.py @@ -6,7 +6,7 @@ class ReceiptsClient: def __init__(self, base_url: str, app_id: str, app_key: str): self.request_handler = RequestHandler(base_url, app_id, app_key) - def get(self, entry_hash: str): + def get(self, entry_hash: str, **kwargs): """Gets a receipt for a specific entry from Connect. Args: @@ -15,6 +15,10 @@ def get(self, entry_hash: str): Returns: Receipt object. """ + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") assert isinstance(entry_hash, str) and len(entry_hash) == 64, "entry_hash must be a string of length 64" - return self.request_handler.get("/".join([factom_sdk.utils.consts.RECEIPTS_URL, entry_hash])) + return self.request_handler.get("/".join([factom_sdk.utils.consts.RECEIPTS_URL, entry_hash]), + base_url=base_url, app_id=app_id, app_key=app_key) diff --git a/factom_sdk/request_handler/request_handler.py b/factom_sdk/request_handler/request_handler.py index 21788cb..a83b609 100755 --- a/factom_sdk/request_handler/request_handler.py +++ b/factom_sdk/request_handler/request_handler.py @@ -20,20 +20,54 @@ def __init__(self, base_url: str, app_id: str, app_key: str): self.app_id = app_id self.app_key = app_key - def _generic_request(self, method, endpoint, data: dict = None, params: dict = None): + def _generic_request(self, method, endpoint, **kwargs): + data = kwargs.get("data", None) + params = kwargs.get("params", None) + app_id = kwargs.get("app_id") + if app_id is None: + app_id = self.app_id + if not isinstance(app_id, str): + raise Exception("The app_id provided for override is not valid.") + app_key = kwargs.get("app_key") + if app_key is None: + app_key = self.app_key + if not isinstance(app_key, str): + raise Exception("The app_key provided for override is not valid.") headers = { - "app_id": self.app_id, - "app_key": self.app_key + "app_id": app_id, + "app_key": app_key } - response = requests.request(method, urljoin(self.base_url, endpoint), params=params, json=data, headers=headers) + base_url = kwargs.get("base_url") + if base_url is None: + base_url = self.base_url + if not validators.url(base_url): + raise Exception("The base_url provided for override is not valid.") + if not base_url.endswith("/"): + base_url += "/" + + response = requests.request(method, + urljoin(base_url, endpoint), + params=params, + json=data, + headers=headers) try: response.raise_for_status() return CommonUtil.decode_response(response.json()) except requests.HTTPError as error: raise error - def get(self, endpoint: str = "", params: dict = None): - return self._generic_request("GET", endpoint, params=params) + def get(self, endpoint: str = "", **kwargs): + params = kwargs.get("params") + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") + return self._generic_request("GET", endpoint, params=params, + base_url=base_url, app_id=app_id, app_key=app_key) - def post(self, endpoint: str = "", data: dict = None): - return self._generic_request("POST", endpoint, data) + def post(self, endpoint: str = "", **kwargs): + data = kwargs.get("data") + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") + return self._generic_request("POST", endpoint, data=data, + base_url=base_url, app_id=app_id, app_key=app_key) diff --git a/factom_sdk/utils/identities/identities_key_util.py b/factom_sdk/utils/identities/identities_key_util.py index 2151928..18e00a0 100644 --- a/factom_sdk/utils/identities/identities_key_util.py +++ b/factom_sdk/utils/identities/identities_key_util.py @@ -8,7 +8,7 @@ class IdentitiesKeyUtil: def __init__(self, base_url: str, app_id: str, app_key: str): self.request_handler = RequestHandler(base_url, app_id, app_key) - def get(self, identity_chain_id: str, key: str): + def get(self, identity_chain_id: str, key: str, **kwargs): """Gets information about a specific public key for a given Identity, including the heights at which the key was activated and retired if applicable. @@ -19,6 +19,9 @@ def get(self, identity_chain_id: str, key: str): Returns: Identity key object. """ + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") if not identity_chain_id: raise Exception("identity_chain_id is required.") if not key: @@ -26,20 +29,23 @@ def get(self, identity_chain_id: str, key: str): if not KeyCommon.validate_checksum(key): raise Exception("key is invalid.") return self.request_handler.get("/".join([factom_sdk.utils.consts.IDENTITY_URL, identity_chain_id, - factom_sdk.utils.consts.KEYS_STRING, key])) + factom_sdk.utils.consts.KEYS_STRING, key]), + base_url=base_url, app_id=app_id, app_key=app_key) - def list(self, identity_chain_id: str, limit: int = -1, offset: int = -1): + def list(self, identity_chain_id: str, **kwargs): """Returns all of the keys that were ever active for this Identity. Results are paginated. Args: identity_chain_id (str): The unique identifier of the identity chain whose keys are being requested. - limit (:obj:`int`, optional): The maximum number of keys you would like to be returned. - offset (:obj:`int`, optional): The key index (in number of keys from the first key) to start from in the - list of all keys. Returns: List identity key object. """ + limit = kwargs.get("limit", -1) + offset = kwargs.get("offset", -1) + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") if not identity_chain_id: raise Exception("identity_chain_id is required.") data = {} @@ -52,10 +58,11 @@ def list(self, identity_chain_id: str, limit: int = -1, offset: int = -1): if offset > -1: data["offset"] = offset return self.request_handler.get("/".join([factom_sdk.utils.consts.IDENTITY_URL, identity_chain_id, - factom_sdk.utils.consts.KEYS_STRING]), data) + factom_sdk.utils.consts.KEYS_STRING]), + params=data, + base_url=base_url, app_id=app_id, app_key=app_key) - def replace(self, identity_chain_id: str, old_public_key: str, signer_private_key: str, - new_public_key: str = None, callback_url: str = "", callback_stages: list = None): + def replace(self, identity_chain_id: str, old_public_key: str, signer_private_key: str, **kwargs): """Creates an entry in the Identity Chain for a key replacement. Args: @@ -63,17 +70,16 @@ def replace(self, identity_chain_id: str, old_public_key: str, signer_private_ke old_public_key (str): base58 string in Idpub format. The public key to be retired and replaced. signer_private_key (str): base58 string in Idsec format. The private key to use to create the signature, which must be the same or higher priority than the public key to be replaced. - new_public_key (:obj:`str`, optional): base58 string in Idpub format. The new public key to be activated - and take its place. - callback_url (:obj:`str`, optional): The URL you would like the callbacks to be sent to. - callback_stages (:obj:`list`, optional): The immutability stages you'd like to be notified about. This list - can include any or all of these three stages: `replicated`, `factom`, and `anchored` Returns: Replacement result object. """ - if callback_stages is None: - callback_stages = [] + new_public_key = kwargs.get("new_public_key", None) + callback_url = kwargs.get("callback_url", "") + callback_stages = kwargs.get("callback_stages", []) + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") if not identity_chain_id: raise Exception("identity_chain_id is required.") if not old_public_key: @@ -112,7 +118,9 @@ def replace(self, identity_chain_id: str, old_public_key: str, signer_private_ke if callback_stages: data["callback_stages"] = callback_stages response = self.request_handler.post("/".join([factom_sdk.utils.consts.IDENTITY_URL, identity_chain_id, - factom_sdk.utils.consts.KEYS_STRING]), data) + factom_sdk.utils.consts.KEYS_STRING]), + data=data, + base_url=base_url, app_id=app_id, app_key=app_key) if new_public_key is None: response["key_pair"] = key_pair return response diff --git a/factom_sdk/utils/validate_signature_util.py b/factom_sdk/utils/validate_signature_util.py index 58122e2..23db64b 100644 --- a/factom_sdk/utils/validate_signature_util.py +++ b/factom_sdk/utils/validate_signature_util.py @@ -6,7 +6,12 @@ class ValidateSignatureUtil: @staticmethod - def validate_signature(obj: dict, validate_for_chain: bool = True, request_handler=None): + def validate_signature(obj: dict, **kwargs): + validate_for_chain = kwargs.get("validate_for_chain", True) + request_handler = kwargs.get("request_handler", None) + base_url = kwargs.get("base_url") + app_id = kwargs.get("app_id") + app_key = kwargs.get("app_key") external_ids = obj["data"]["external_ids"] try: @@ -41,7 +46,8 @@ def validate_signature(obj: dict, validate_for_chain: bool = True, request_handl key_height = obj["data"]["dblock"]["height"] try: key_response = request_handler.get("/".join([factom_sdk.utils.consts.IDENTITIES_URL, signer_chain_id, - factom_sdk.utils.consts.KEYS_STRING, signer_public_key])) + factom_sdk.utils.consts.KEYS_STRING, signer_public_key]), + base_url=base_url, app_id=app_id, app_key=app_key) if key_response["data"]["retired_height"] is not None and \ not ((key_response["data"]["activated_height"] <= key_height) and (key_height <= key_response["data"]["retired_height"])): diff --git a/sample_app/simulate_notary.py b/sample_app/simulate_notary.py index 06de965..1d9ada8 100644 --- a/sample_app/simulate_notary.py +++ b/sample_app/simulate_notary.py @@ -135,7 +135,8 @@ def simulate_notary(): # In order to display the External Ids array then we need to get entry. However, we don't need # to validate the signature so in this step pass in signature_validation=False get_entry_response = factom_client.chains.entries.get(chain["data"]["chain_id"], - create_entry_response["entry_hash"], False) + create_entry_response["entry_hash"], + signature_validation=False) entry_created_time = get_entry_response["data"]["external_ids"][5] # Search chain @@ -153,7 +154,7 @@ def simulate_notary(): # to make sure search function only return one result entry_search_input = ["DocumentEntry", "doc987", entry_created_time] entry_search_result = factom_client.chains.entries.search(chain_w_validation["chain"]["data"]["chain_id"], - entry_search_input) + external_ids=entry_search_input) # Retrieve Blockchain Data aren't always necessary # because it is common practice to store the chain_id and entry_hash within your own database. diff --git a/tests/test_api_info_client.py b/tests/test_api_info_client.py index 00973fc..0e71ae9 100644 --- a/tests/test_api_info_client.py +++ b/tests/test_api_info_client.py @@ -12,7 +12,7 @@ def tearDown(self): self.info_client = None def test_init(self): - """Check init identity client""" + """Check init api info client""" self.assertTrue(isinstance(self.info_client.request_handler, RequestHandler)) def test_get_info(self): diff --git a/tests/test_chains_client.py b/tests/test_chains_client.py index d5c78bd..2a68930 100644 --- a/tests/test_chains_client.py +++ b/tests/test_chains_client.py @@ -29,11 +29,11 @@ def test_get(self): def signature_validation(params: dict): return "valid_signature" - response = self.chains_client.get("123124", signature_validation) + response = self.chains_client.get("123124", signature_validation=signature_validation) self.assertIsNotNone(response) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_get: mock_get.return_value.ok = True - response = self.chains_client.get("123124", False) + response = self.chains_client.get("123124", signature_validation=False) self.assertIsNotNone(response) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_get: @@ -44,7 +44,7 @@ def signature_validation(params: dict): def test_create(self): """Check create chain""" with self.assertRaises(Exception) as cm: - self.chains_client.create("", ["123"]) + self.chains_client.create("", external_ids=["123"]) self.assertTrue("content is required." in str(cm.exception)) with self.assertRaises(Exception) as cm: @@ -52,51 +52,54 @@ def test_create(self): self.assertTrue("at least 1 external_id is required." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.chains_client.create("123", "1") + self.chains_client.create("123", external_ids="1") self.assertTrue("external_ids must be an array." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.chains_client.create("123", ["1"], "idsec") + self.chains_client.create("123", external_ids=["1"], signer_private_key="idsec") self.assertTrue("signer_chain_id is required when passing a signer_private_key." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.chains_client.create("123", ["1"], "idsec", "123") + self.chains_client.create("123", external_ids=["1"], signer_private_key="idsec", signer_chain_id="123") self.assertTrue("signer_private_key is invalid." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.chains_client.create("123", ["1"], "", "123") + self.chains_client.create("123", external_ids=["1"], signer_chain_id="123") self.assertTrue("signer_private_key is required when passing a signer_chain_id." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.chains_client.create("123", ["1"], "", "", "google") + self.chains_client.create("123", external_ids=["1"], callback_url="google") self.assertTrue("callback_url is an invalid url format." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.chains_client.create("123", ["1"], "", "", "", "123") + self.chains_client.create("123", external_ids=["1"], callback_stages="123") self.assertTrue("callback_stages must be an array." in str(cm.exception)) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_post: mock_post.return_value.ok = True - response = self.chains_client.create("123", ["1"], "", "", "http://google.com", ["123"]) + response = self.chains_client.create("123", + external_ids=["1"], + callback_url="http://google.com", + callback_stages=["123"]) self.assertIsNotNone(response) def test_list(self): """Check get all chains""" with self.assertRaises(Exception) as cm: - self.chains_client.list("1") + self.chains_client.list(limit="1") self.assertTrue("limit must be an integer." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.chains_client.list(1, "1") + self.chains_client.list(limit=1, offset="1") self.assertTrue("offset must be an integer." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.chains_client.list(1, 1, "1") + self.chains_client.list(limit=1, offset=1, stages="1") self.assertTrue("stages must be an array." in str(cm.exception)) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_get: mock_get.return_value.ok = True - response = self.chains_client.list(1, 1, ["123"]) + response = self.chains_client.list(limit=1, offset=1, stages=["123"]) self.assertIsNotNone(response) def test_search(self): @@ -110,21 +113,21 @@ def test_search(self): self.assertTrue("external_ids must be an array." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.chains_client.search(["123"], "1") + self.chains_client.search(["123"], limit="1") self.assertTrue("limit must be an integer." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.chains_client.search(["123"], 1, "1") + self.chains_client.search(["123"], limit=1, offset="1") self.assertTrue("offset must be an integer." in str(cm.exception)) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_post: mock_post.return_value.ok = True - response = self.chains_client.search(["123"], 1, 1) + response = self.chains_client.search(["123"], limit=1, offset=1) self.assertIsNotNone(response) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_post: mock_post.return_value.ok = True - response = self.chains_client.search(["123"], -1, 1) + response = self.chains_client.search(["123"], limit=-1, offset=1) self.assertIsNotNone(response) @@ -140,24 +143,35 @@ def tearDown(self): def test_create(self): """Check create chain""" with self.assertRaises(Exception) as cm: - self.chains_client.create("123", "123") + self.chains_client.create("123", external_ids="123") self.assertTrue("external_ids must be an array." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.chains_client.create("123", []) + self.chains_client.create("123") self.assertTrue("signer_private_key is required." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.chains_client.create("123", [], "idsec") + self.chains_client.create("123", signer_private_key="idsec") self.assertTrue("signer_private_key is invalid." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.chains_client.create("123", [], "idsec1Xbja4exmHFNgVSsk7VipNi4mwt6BjQFEZFCohs4Y7TzfhHoy6") + self.chains_client.create("123", + signer_private_key="idsec1Xbja4exmHFNgVSsk7VipNi4mwt6BjQFEZFCohs4Y7TzfhHoy6") self.assertTrue("signer_chain_id is required." in str(cm.exception)) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_post: mock_post.return_value.ok = True - response = self.chains_client.create("123", [], "idsec1Xbja4exmHFNgVSsk7VipNi4mwt6BjQFEZFCohs4Y7TzfhHoy6", - "171e5851451ce6f2d9730c1537da4375feb442870d835c54a1bca8ffa7e2bda7") + response = self.chains_client.create("123", + signer_private_key="idsec1Xbja4exmHFNgVSsk7VipNi4mwt6BjQFEZFCohs4Y7TzfhHoy6", + signer_chain_id="171e5851451ce6f2d9730c1537da4375feb442870d835c54a1bca8ffa7e2bda7") + self.assertIsNotNone(response) + + with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_post: + mock_post.return_value.ok = True + response = self.chains_client.create("123", + external_ids=["1"], + callback_url="http://google.com", + callback_stages=["123"], + automatic_signing=False) self.assertIsNotNone(response) diff --git a/tests/test_entries_client.py b/tests/test_entries_client.py index b778e64..e124567 100644 --- a/tests/test_entries_client.py +++ b/tests/test_entries_client.py @@ -18,16 +18,16 @@ def test_init(self): def test_get(self): """Check get entry info""" with self.assertRaises(Exception) as cm: - self.entries_client.get("", "", False) + self.entries_client.get("", "") self.assertTrue("chain_id is required." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.get("123", "", False) + self.entries_client.get("123", "") self.assertTrue("entry_hash is required." in str(cm.exception)) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_get: mock_get.return_value.ok = True - response = self.entries_client.get("123", "123", False) + response = self.entries_client.get("123", "123", signature_validation=False) self.assertIsNotNone(response) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_get: @@ -41,7 +41,7 @@ def test_get(self): def signature_validation(params: dict): return "valid_signature" - response = self.entries_client.get("123", "123", signature_validation) + response = self.entries_client.get("123", "123", signature_validation=signature_validation) self.assertIsNotNone(response) def test_create(self): @@ -55,23 +55,25 @@ def test_create(self): self.assertTrue("at least 1 external_id is required." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.create("123", "", "123") + self.entries_client.create("123", "", external_ids="123") self.assertTrue("external_ids must be an array." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.create("123", "", ["123"], "idsec") + self.entries_client.create("123", "", external_ids=["123"], signer_private_key="idsec") self.assertTrue("signer_chain_id is required when passing a signer_private_key." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.create("123", "", ["123"], "idsec", "123") + self.entries_client.create("123", "", external_ids=["123"], + signer_private_key="idsec", signer_chain_id="123") self.assertTrue("signer_private_key is invalid." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.create("123", "", ["123"], "", "123") + self.entries_client.create("123", "", external_ids=["123"], + signer_private_key="", signer_chain_id="123") self.assertTrue("signer_private_key is required when passing a signer_chain_id." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.create("123", "", ["123"]) + self.entries_client.create("123", "", external_ids=["123"]) self.assertTrue("content is required." in str(cm.exception)) def test_list(self): @@ -81,20 +83,20 @@ def test_list(self): self.assertTrue("chain_id is required." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.list("123", "1") + self.entries_client.list("123", limit="1") self.assertTrue("limit must be an integer." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.list("123", 1, "1") + self.entries_client.list("123", limit=1, offset="1") self.assertTrue("offset must be an integer." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.list("123", 1, 1, "1") + self.entries_client.list("123", limit=1, offset=1, stages="1") self.assertTrue("stages must be an array." in str(cm.exception)) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_get: mock_get.return_value.ok = True - response = self.entries_client.list("123", 1, 1, ["1"]) + response = self.entries_client.list("123", limit=1, offset=1, stages=["1"]) self.assertIsNotNone(response) def test_get_first(self): @@ -110,7 +112,7 @@ def test_get_first(self): with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_get: mock_get.return_value.ok = True - response = self.entries_client.get_first("123", False) + response = self.entries_client.get_first("123", signature_validation=False) self.assertIsNotNone(response) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_get: @@ -119,7 +121,7 @@ def test_get_first(self): def signature_validation(params: dict): return "valid_signature" - response = self.entries_client.get_first("123", signature_validation) + response = self.entries_client.get_first("123", signature_validation=signature_validation) self.assertIsNotNone(response) def test_get_last(self): @@ -135,7 +137,7 @@ def test_get_last(self): with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_get: mock_get.return_value.ok = True - response = self.entries_client.get_last("123", False) + response = self.entries_client.get_last("123", signature_validation=False) self.assertIsNotNone(response) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_get: @@ -144,7 +146,7 @@ def test_get_last(self): def signature_validation(params: dict): return "valid_signature" - response = self.entries_client.get_last("123", signature_validation) + response = self.entries_client.get_last("123", signature_validation=signature_validation) self.assertIsNotNone(response) def test_search(self): @@ -162,21 +164,21 @@ def test_search(self): self.assertTrue("external_ids must be an array." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.search("123", ["1"], "1") + self.entries_client.search("123", ["1"], limit="1") self.assertTrue("limit must be an integer." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.search("123", ["1"], 1, "1") + self.entries_client.search("123", ["1"], limit=1, offset="1") self.assertTrue("offset must be an integer." in str(cm.exception)) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_post: mock_post.return_value.ok = True - response = self.entries_client.search("123", ["1"], 1, 1) + response = self.entries_client.search("123", ["1"], limit=1, offset=1) self.assertIsNotNone(response) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_post: mock_post.return_value.ok = True - response = self.entries_client.search("123", ["1"], -1, 1) + response = self.entries_client.search("123", ["1"], limit=-1, offset=1) self.assertIsNotNone(response) @@ -190,36 +192,37 @@ def tearDown(self): def test_create(self): """Check create entry""" with self.assertRaises(Exception) as cm: - self.entries_client.create("123", "", "123", "idsec", "123") + self.entries_client.create("123", "", external_ids="123") self.assertTrue("external_ids must be an array." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.create("123", "", ["123"], "", "") + self.entries_client.create("123", "", external_ids=["123"]) self.assertTrue("signer_private_key is required." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.create("123", "", ["123"], "idsec", "") + self.entries_client.create("123", "", external_ids=["123"], signer_private_key="idsec") self.assertTrue("signer_private_key is invalid." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.create("123", "", ["123"], - "idsec1Xbja4exmHFNgVSsk7VipNi4mwt6BjQFEZFCohs4Y7TzfhHoy6", "") + self.entries_client.create("123", "", external_ids=["123"], + signer_private_key="idsec1Xbja4exmHFNgVSsk7VipNi4mwt6BjQFEZFCohs4Y7TzfhHoy6") self.assertTrue("signer_chain_id is required." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.create("123", "123", ["123"], - "idsec1Xbja4exmHFNgVSsk7VipNi4mwt6BjQFEZFCohs4Y7TzfhHoy6", "123", "google") + self.entries_client.create("123", "123", external_ids=["123"], + signer_private_key="idsec1Xbja4exmHFNgVSsk7VipNi4mwt6BjQFEZFCohs4Y7TzfhHoy6", + signer_chain_id="123", callback_url="google") self.assertTrue("callback_url is an invalid url format." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.entries_client.create("123", "123", ["123"], - "idsec1Xbja4exmHFNgVSsk7VipNi4mwt6BjQFEZFCohs4Y7TzfhHoy6", - "123", "", "123") + self.entries_client.create("123", "123", external_ids=["123"], + signer_private_key="idsec1Xbja4exmHFNgVSsk7VipNi4mwt6BjQFEZFCohs4Y7TzfhHoy6", + signer_chain_id="123", callback_stages="123") self.assertTrue("callback_stages must be an array." in str(cm.exception)) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_post: mock_post.return_value.ok = True - response = self.entries_client.create("123", "123", ["123"], - "idsec1Xbja4exmHFNgVSsk7VipNi4mwt6BjQFEZFCohs4Y7TzfhHoy6", - "123", "http://google.com", ["123"]) + response = self.entries_client.create("123", "123", external_ids=["123"], + signer_private_key="idsec1Xbja4exmHFNgVSsk7VipNi4mwt6BjQFEZFCohs4Y7TzfhHoy6", + signer_chain_id="123", callback_url="http://google.com", callback_stages=["123"]) self.assertIsNotNone(response) diff --git a/tests/test_identities_client.py b/tests/test_identities_client.py index 0dc1f20..40232cd 100644 --- a/tests/test_identities_client.py +++ b/tests/test_identities_client.py @@ -18,23 +18,23 @@ def test_init(self): def test_create(self): """Check create identity""" with self.assertRaises(Exception) as cm: - self.identities_client.create("", "") + self.identities_client.create("") self.assertTrue("at least 1 name is required." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.identities_client.create("123", "123") + self.identities_client.create("123") self.assertTrue("names must be an array." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.identities_client.create(["123"], []) + self.identities_client.create(["123"], keys=[]) self.assertTrue("at least 1 key is required." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.identities_client.create(["123"], "123") + self.identities_client.create(["123"], keys="123") self.assertTrue("keys must be an array." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.identities_client.create(["123"], ["idpub"], "", "factom") + self.identities_client.create(["123"], keys=["idpub"], callback_stages="factom") self.assertTrue("callback_stages must be an array." in str(cm.exception)) with self.assertRaises(Exception) as cm: @@ -48,7 +48,7 @@ def test_create(self): "error": "key is invalid", }, ] - self.identities_client.create(["123"], [ + self.identities_client.create(["123"], keys=[ "123", "123", "idpub2TWHFrWrJxVEmbeXnMRWeKBdFp7bEByosS1phV1bH7NS99zHF9" @@ -62,7 +62,7 @@ def test_create(self): "error": "key is duplicated, keys must be unique.", }, ] - self.identities_client.create(["123"], [ + self.identities_client.create(["123"], keys=[ "idpub2TWHFrWrJxVEmbeXnMRWeKBdFp7bEByosS1phV1bH7NS99zHF9", "idpub2TWHFrWrJxVEmbeXnMRWeKBdFp7bEByosS1phV1bH7NS99zHF9", "idpub2TWHFrWrJxVEmbeXnMRWeKBdFp7bEByosS1phV1bH7NS99zHF9", @@ -70,11 +70,12 @@ def test_create(self): self.assertTrue(str(errors) in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.identities_client.create(["123"], [ + self.identities_client.create(["123"], keys=[ "idpub2TWHFrWrJxVEmbeXnMRWeKBdFp7bEByosS1phV1bH7NS99zHF9", "idpub2FEZg6PwVuDXfsxEMinnqVfgjuNS2GzMSQwJgTdmUFQaoYpTnv", "idpub1tkTRwxonwCfsvTkk5enWzbZgQSRpWDYtdzPUnq83AgQtecSgc", - ], "callback.com", ["factom", "replicated"]) + ], callback_url="callback.com", + callback_stages=["factom", "replicated"]) self.assertTrue("callback_url is an invalid url format." in str(cm.exception)) with self.assertRaises(Exception) as cm: @@ -119,9 +120,8 @@ def test_create(self): "The primary benefit of using Identities within your application the ability to verify that a certain user/device/organization/etc. actually signed and published a certain message that you see in your chain. Let is go through an example of how this creation of a signed entry works for an identity we made already", "The primary benefit of using Identities within your application the ability to verify that a certain user/device/organization/etc. actually signed and published a certain message that you see in your chain. Let is go through an example of how this creation of a signed entry works for an identity we made already", "The primary benefit of using Identities within your application the ability to verify that a certain user/device/organization/etc. actually signed and published a certain message that you see in your chain. Let is go through an example of how this creation of a signed entry works for an identity we made already", ], - None, - "https://callback.com", - ["factom", "replicated"] + callback_url="https://callback.com", + callback_stages=["factom", "replicated"] ) self.assertTrue("Entry size 12771 must be less than 10240. Use less/shorter names or less keys." in str(cm.exception)) @@ -130,9 +130,8 @@ def test_create(self): mock_post.return_value.ok = True response = self.identities_client.create( ["123"], - None, - "https://callback.com", - ["factom", "replicated"] + callback_url="https://callback.com", + callback_stages=["factom", "replicated"] ) self.assertIsNotNone(response) @@ -173,67 +172,67 @@ def test_key_list(self): self.assertTrue("identity_chain_id is required." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.identities_client.keys.list("123", "123", "123") + self.identities_client.keys.list("123", limit="123", offset="123") self.assertTrue("limit must be an integer." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.identities_client.keys.list("123", 123, "123") + self.identities_client.keys.list("123", limit=123, offset="123") self.assertTrue("offset must be an integer." in str(cm.exception)) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_get: mock_get.return_value.ok = True - response = self.identities_client.keys.list("123", 123, 123) + response = self.identities_client.keys.list("123", limit=123, offset=123) self.assertIsNotNone(response) def test_key_replace(self): """Check create identity key replacement""" with self.assertRaises(Exception) as cm: - self.identities_client.keys.replace("", "", "", "") + self.identities_client.keys.replace("", "", "") self.assertTrue("identity_chain_id is required." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.identities_client.keys.replace("123", "", "", "") + self.identities_client.keys.replace("123", "", "") self.assertTrue("old_public_key is required." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.identities_client.keys.replace("123", "123", "", "") + self.identities_client.keys.replace("123", "123", "") self.assertTrue("signer_private_key is required." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.identities_client.keys.replace("123", "123", "123", "") + self.identities_client.keys.replace("123", "123", "123", new_public_key="") self.assertTrue("new_public_key is required." in str(cm.exception)) with self.assertRaises(Exception) as cm: - self.identities_client.keys.replace("123", "idpub1", "idsec", "idpub2") + self.identities_client.keys.replace("123", "idpub1", "idsec") self.assertTrue("old_public_key is an invalid public key." in str(cm.exception)) with self.assertRaises(Exception) as cm: self.identities_client.keys.replace("123", "idpub2TWHFrWrJxVEmbeXnMRWeKBdFp7bEByosS1phV1bH7NS99zHF9", - "idsec", "idpub2") + "idsec") self.assertTrue("signer_private_key is invalid." in str(cm.exception)) with self.assertRaises(Exception) as cm: self.identities_client.keys.replace("123", "idpub2TWHFrWrJxVEmbeXnMRWeKBdFp7bEByosS1phV1bH7NS99zHF9", "idsec1Xbja4exmHFNgVSsk7VipNi4mwt6BjQFEZFCohs4Y7TzfhHoy6", - "idpub2") + new_public_key="idpub2") self.assertTrue("new_public_key is an invalid public key." in str(cm.exception)) with self.assertRaises(Exception) as cm: self.identities_client.keys.replace("123", "idpub2TWHFrWrJxVEmbeXnMRWeKBdFp7bEByosS1phV1bH7NS99zHF9", "idsec1Xbja4exmHFNgVSsk7VipNi4mwt6BjQFEZFCohs4Y7TzfhHoy6", - "idpub2TWHFrWrJxVEmbeXnMRWeKBdFp7bEByosS1phV1bH7NS99zHF9", - "", "factom") + new_public_key="idpub2TWHFrWrJxVEmbeXnMRWeKBdFp7bEByosS1phV1bH7NS99zHF9", + callback_stages="factom") self.assertTrue("callback_stages must be an array." in str(cm.exception)) with self.assertRaises(Exception) as cm: self.identities_client.keys.replace("123", "idpub2TWHFrWrJxVEmbeXnMRWeKBdFp7bEByosS1phV1bH7NS99zHF9", "idsec1Xbja4exmHFNgVSsk7VipNi4mwt6BjQFEZFCohs4Y7TzfhHoy6", - "idpub2TWHFrWrJxVEmbeXnMRWeKBdFp7bEByosS1phV1bH7NS99zHF9", - "io.com", ["factom"]) + new_public_key="idpub2TWHFrWrJxVEmbeXnMRWeKBdFp7bEByosS1phV1bH7NS99zHF9", + callback_url="io.com", callback_stages=["factom"]) self.assertTrue("callback_url is an invalid url format." in str(cm.exception)) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_post: diff --git a/tests/test_request_handler.py b/tests/test_request_handler.py index 74808dd..e293e05 100644 --- a/tests/test_request_handler.py +++ b/tests/test_request_handler.py @@ -47,6 +47,15 @@ def test_send_get_request(self): mock_get.return_value.ok = True response = self.request_handler.get() self.assertIsNotNone(response) + with self.assertRaises(Exception) as cm: + self.request_handler.get(base_url="io.co") + self.assertTrue("The base_url provided for override is not valid." in str(cm.exception)) + with self.assertRaises(Exception) as cm: + self.request_handler.get(app_id=1) + self.assertTrue("The app_id provided for override is not valid." in str(cm.exception)) + with self.assertRaises(Exception) as cm: + self.request_handler.get(app_key=1) + self.assertTrue("The app_key provided for override is not valid." in str(cm.exception)) def test_send_post_request(self): """Check Send post request successfully""" diff --git a/tests/test_validate_signature_util.py b/tests/test_validate_signature_util.py index 7533a37..a06179b 100644 --- a/tests/test_validate_signature_util.py +++ b/tests/test_validate_signature_util.py @@ -25,7 +25,7 @@ def test_validate_signature(self): "content": "123" } } - result = ValidateSignatureUtil.validate_signature(data, True, self.request_handler) + result = ValidateSignatureUtil.validate_signature(data, request_handler=self.request_handler) self.assertEqual("not_signed/invalid_chain_format", result) data = { @@ -44,7 +44,7 @@ def test_validate_signature(self): "content": "123" } } - result = ValidateSignatureUtil.validate_signature(data, True, self.request_handler) + result = ValidateSignatureUtil.validate_signature(data, request_handler=self.request_handler) self.assertEqual("not_signed/invalid_chain_format", result) data = { @@ -63,7 +63,7 @@ def test_validate_signature(self): "content": "123" } } - result = ValidateSignatureUtil.validate_signature(data, True, self.request_handler) + result = ValidateSignatureUtil.validate_signature(data, request_handler=self.request_handler) self.assertEqual("not_signed/invalid_chain_format", result) data = { @@ -88,7 +88,7 @@ def test_validate_signature(self): mock_error.response = Mock() mock_error.response.status_code = 404 mock_get.side_effect = mock_error - response = ValidateSignatureUtil.validate_signature(data, True, self.request_handler) + response = ValidateSignatureUtil.validate_signature(data, request_handler=self.request_handler) self.assertEqual("key_not_found", response) with self.assertRaises(HTTPError) as cm: @@ -97,7 +97,7 @@ def test_validate_signature(self): mock_error.response = Mock() mock_error.response.status_code = 500 mock_get.side_effect = mock_error - ValidateSignatureUtil.validate_signature(data, True, self.request_handler) + ValidateSignatureUtil.validate_signature(data, request_handler=self.request_handler) self.assertTrue("" in str(cm.exception)) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_get: @@ -110,7 +110,7 @@ def test_validate_signature(self): } mock_get.return_value.ok = True mock_get.return_value.json.return_value = json - response = ValidateSignatureUtil.validate_signature(data, True, self.request_handler) + response = ValidateSignatureUtil.validate_signature(data, request_handler=self.request_handler) self.assertEqual("retired_key", response) data = { @@ -140,7 +140,8 @@ def test_validate_signature(self): } mock_get.return_value.ok = True mock_get.return_value.json.return_value = json - response = ValidateSignatureUtil.validate_signature(data, False, self.request_handler) + response = ValidateSignatureUtil.validate_signature(data, validate_for_chain=False, + request_handler=self.request_handler) self.assertEqual("retired_key", response) with patch("factom_sdk.request_handler.request_handler.requests.request") as mock_get: @@ -153,5 +154,6 @@ def test_validate_signature(self): } mock_get.return_value.ok = True mock_get.return_value.json.return_value = json - response = ValidateSignatureUtil.validate_signature(data, False, self.request_handler) + response = ValidateSignatureUtil.validate_signature(data, validate_for_chain=False, + request_handler=self.request_handler) self.assertEqual("invalid_signature", response)