Skip to main content

Python client for Original.

Project description

Official Python SDK for Original API

Table of Contents

✨ Getting started

Ensure you have registered for an account at Original before getting started. You will need to create an app and note down your API key and secret from the API Keys page to use the Original SDK.

Install Original

$ pip install original-sdk

📚 Documentation

Initialization

The Original SDK is set up to expose the Original API.

Read the full Original API documentation.

Create a new instance of the Original client by passing in your api key and secret, with the environment associated with that app.

Development

For development apps, you must pass the environment:

from original_sdk import OriginalClient, Environment

client = OriginalClient(api_key='YOUR_DEV_APP_API_KEY', api_secret='YOUR_DEV_APP_SECRET', env=Environment.Development)

Production

For production apps, you can optionally pass the production environment:

from original_sdk import OriginalClient, Environment

client = OriginalClient(api_key='YOUR_PROD_APP_API_KEY', api_secret='YOUR_PROD_APP_SECRET', env=Environment.Production)

or omit the environment, which will default to production:

from original_sdk import OriginalClient

client = OriginalClient(api_key='YOUR_PROD_APP_API_KEY', api_secret='YOUR_PROD_APP_SECRET')

Async Client

There is also an async client available for use with async/await syntax:

from original_sdk import OriginalAsyncClient, Environment

client = OriginalAsyncClient(api_key='YOUR_DEV_APP_API_KEY', api_secret='YOUR_DEV_APP_SECRET', env=Environment.Development)

User

The user methods exposed by the sdk are used to create and retrieve users from the Original API.

Create a new user

# Returns a response object. Access the user's UID through the `data` attribute.
create_response = client.create_user(email='YOUR_EMAIL', client_id='YOUR_CLIENT_ID')
new_user_uid = create_response['data']['uid']
# Sample create_response:
{
    "success": True,
    "data": {
        "uid": "175324281338"
    }
}

Get a user by UID

# Get a user by UID
# Returns their details in a response object if the user exists. If not, a 404 client error will be raised.
user_response = client.get_user(new_user_uid)
user_details = user_response['data']  # Contains user details such as UID, email, etc.
# Sample user_response:
{
    "success": True,
    "data": {
        "uid": "754566475542",
        "client_id": "user_client_id",
        "created_at": "2024-02-26T13:12:31.798296Z",
        "email": "user_email@email.com",
        "wallet_address": "0xa22f2dfe189ed3d16bb5bda5e5763b2919058e40"
    }
}

Get a user by email

# Get a user by email
# Attempts to retrieve a user by their email address. If the user does not exist, `data` will be None.
user_by_email_response = client.get_user_by_email('YOUR_EMAIL')
user_by_email_details = user_by_email_response['data']
# Sample user_by_email_response on success:
{
    "success": True,
    "data": {
        "uid": "754566475542",
        "client_id": "user_client_id",
        "created_at": "2024-02-26T13:12:31.798296Z",
        "email": "user_email@email.com",
        "wallet_address": "0xa22f2dfe189ed3d16bb5bda5e5763b2919058e40"
    }
}

# Sample user_by_email_response (if user does not exist) on failure
{
    "success": False,
    "data": None
}

Get a user by client ID

# Get a user by client ID
# Retrieves a user by their client ID. If the user does not exist, `data` will be None.
user_by_client_id_response = client.get_user_by_client_id('YOUR_CLIENT_ID')
user_by_client_id_details = user_by_client_id_response['data']
# Sample user_by_client_id_response on success:
{
    "success": True,
    "data": {
        "uid": "754566475542",
        "client_id": "user_client_id",
        "created_at": "2024-02-26T13:12:31.798296Z",
        "email": "user_email@email.com",
        "wallet_address": "0xa22f2dfe189ed3d16bb5bda5e5763b2919058e40"
    }
}
# Sample user_by_client_id_response on failure:
{
    "success": False,
    "data": None
}

Asset

The asset methods exposed by the sdk are used to create (mint) assets and retrieve assets from the Original API.

Create a new asset

# prepare the new asset params
new_asset_params = {
    "user_uid": "324167489835",
    "client_id": "client_id_1",
    "collection_uid": "221137489875",
    "data": {
        "name": "Dave Starbelly",
        "unique_name": True,
        "image_url": "https://storage.googleapis.com/opensea-prod.appspot.com/puffs/3.png",
        "store_image_on_ipfs": True,
        "description": "Friendly OpenSea Creature that enjoys long swims in the ocean.",
        "external_url": "https://openseacreatures.io/3",
        "attributes": [
            {
                "trait_type": "Base",
                "value": "Starfish"
            },
            {
                "trait_type": "Stamina Increase",
                "display_type": "boost_percentage",
                "value": 10
            },
        ]
    }
}

# Create a new asset
create_asset_response = client.create_asset(**new_asset_params)
new_asset_uid = create_asset_response['data']['uid']
# Sample create_asset_response:
{
    "success": True,
    "data": {
        "uid": "151854912345"
    }
}

Get an asset by asset UID

# Get an asset by UID, returns the asset details in a response object if the asset exists. If not, a 404 client error will be raised.
asset_response = client.get_asset(new_asset_uid)
asset_details = asset_response['data']
# Sample asset_response:
{
    "success": True,
    "data": {
        "uid": "151854912345",
        "name": "random name #2",
        "client_id": "asset_client_id_1",
        "collection_uid": "471616646163",
        "collection_name": "Test SDK Collection 1",
        "token_id": 2,
        "created_at": "2024-02-16T11:33:19.577827Z",
        "is_minted": True,
        "is_burned": False,
        "is_transferring": False,
        "is_transferable": True,
        "is_editing": False,
        "mint_for_user_uid": "885810911461",
        "owner_user_uid": "885810911461",
        "owner_address": "0x32e28bfe647939d073d39113c697a11e3065ea97",
        "metadata": {
            "name": "random name",
            "image_url": "https://cryptopunks.app/cryptopunks/cryptopunk1081.png",
            "description": "nft_description",
            "original_id": "151854912345",
            "external_url": "external_url@example.com",
            "org_image_url": "https://cryptopunks.app/cryptopunks/cryptopunk1081.png"
        },
        "explorer_url": "https://mumbai.polygonscan.com/token/0x124a6755ee787153bb6228463d5dc3a02890a7db?a=2",
        "token_uri": "https://storage.googleapis.com/{...}.json"
    }
}

Get assets by user UID

# Get assets by the owner's UID
assets_response = client.get_assets_by_user_uid("user_uid")
assets_list = assets_response['data']
# Sample assets_response (showing one asset for brevity, wrapped in a response object):
{
    "success": True,
    "data": [
        {
            "uid": "151854912345",
            "name": "random name #2",
            "client_id": "asset_client_id_1",
            "collection_uid": "471616646163",
            "collection_name": "Test SDK Collection 1",
            "token_id": 2,
            "created_at": "2024-02-16T11:33:19.577827Z",
            "is_minted": True,
            "is_burned": False,
            "is_transferring": False,
            "is_transferable": True,
            "is_editing": False,
            "mint_for_user_uid": "885810911461",
            "owner_user_uid": "885810911461",
            "owner_address": "0x32e28bfe647939d073d39113c697a11e3065ea97",
            "metadata": {
                "name": "random name",
                "image_url": "https://cryptopunks.app/cryptopunks/cryptopunk1081.png",
                "description": "nft_description",
                "original_id": "151854912345",
                "external_url": "external_url@example.com",
                "org_image_url": "https://cryptopunks.app/cryptopunks/cryptopunk1081.png"
            },
            "explorer_url": "https://mumbai.polygonscan.com/token/0x124a6755ee787153bb6228463d5dc3a02890a7db?a=2",
            "token_uri": "https://storage.googleapis.com/original-production-media/data/metadata/9ac0dad4-75ae-4406-94fd-1a0f6bf75db3.json"
        }
        # Additional assets would be listed here
    ]
}

Edit an asset

NOTE: Editing an asset will overwrite the existing asset data with the new data provided. If you want to maintain any of the existing data, you must include it in the new data.

NOTE: You must include all the required fields. See https://docs.getoriginal.com/docs/edit-asset for more information.

# prepare the edit asset params
edit_asset_params = {
    "data": {
        "name": "Dave Starbelly Edited",
        "unique_name": True,
        "image_url": "https://storage.googleapis.com/opensea-prod.appspot.com/puffs/3.png",
        "description": "Friendly OpenSea Creature that enjoys long swims in the ocean. Edited",
        "attributes": [
            {
                "trait_type": "Base",
                "value": "Starfish"
            },
        ]
    }
}

# Edits an asset by UID, by passing in the new asset data
edit_asset_response = client.edit_asset(new_asset_uid, **edit_asset_params)
edit_success = edit_asset_response['success']
# Sample edit_asset_response:
{
    "success": True,
    "data": None
}

Transfer

The transfer methods exposed by the sdk are used to transfer assets from one user to another wallet.

Create a new transfer

# Prepare the transfer parameters
transfer_params = {
    "asset_uid": "708469717542",
    "from_user_uid": "149997600351",
    "to_address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
}

# Create a transfer of an asset
transfer_response = client.create_transfer(**transfer_params)
transfer_uid = transfer_response['data']['uid']
# Sample transfer_response:
{
    "success": True,
    "data": {
        "uid": "883072660397"
    }
}

Get a transfer by transfer UID

# Get a transfer by transfer UID, will throw a 404 Not Found error if the transfer does not exist
transfer_response = client.get_transfer("883072660397")
transfer_details = transfer_response['data']
# Sample transfer_response:
{
    "success": True,
    "data": {
        "uid": "883072660397",
        "status": "done",
        "asset_uid": "708469717542",
        "from_user_uid": "149997600351",
        "to_address": "0xe02522d0ac9f53e35a56f42cd5e54fc7b5a12f05",
        "created_at": "2024-02-26T10:20:17.668254Z"
    }
}

Get transfers by user UID

# Get transfers by user UID
transfers_response = client.get_transfers_by_user_uid("149997600351")
transfers_list = transfers_response['data']
# Sample transfers_response:
{
    "success": True,
    "data": [
        {
            "uid": "883072660397",
            "status": "done",
            "asset_uid": "708469717542",
            "from_user_uid": "149997600351",
            "to_address": "0xe02522d0ac9f53e35a56f42cd5e54fc7b5a12f05",
            "created_at": "2024-02-26T10:20:17.668254Z"
        }
        # Additional transfers would be listed here
    ]
}

Burn

The burn methods exposed by the sdk are used to burn assets from a user's wallet.

Create a new burn

# Prepare the burn parameters
burn_params = {
    "asset_uid": "708469717542",
    "from_user_uid": "483581848722",
}

# Create a burn of an asset
burn_response = client.create_burn(**burn_params)
burn_uid = burn_response['data']['uid']
# Sample burn_response:
{
    "success": True,
    "data": {
        "uid": "365684656925",
    }
}

Get a burn by burn UID

# Get a burn by UID, will throw a 404 Not Found error if the burn does not exist
burn_response = client.get_burn("365684656925")
burn_details = burn_response['data']
# Sample burn_response:
{
    "success": True,
    "data": {
        "uid": "365684656925",
        "status": "done",
        "asset_uid": "708469717542",
        "from_user_uid": "483581848722",
        "created_at": "2024-02-26T10:20:17.668254Z"
    }
}

Get burns by user UID

# Get burns by user UID
burns_response = client.get_burns_by_user_uid("483581848722")
burns_list = burns_response['data']
# Sample burns_response:
{
    "success": True,
    "data": [
        {
            "uid": "365684656925",
            "status": "done",
            "asset_uid": "708469717542",
            "from_user_uid": "483581848722",
            "created_at": "2024-02-26T10:22:47.848973Z"
        }
        # Additional burns would be listed here
    ]
}

Deposit

The deposit methods exposed by the sdk are used to return the details for depositing assets.

Get deposit details by user UID

# Get deposit details for a user
deposit_response = client.get_deposit("user_uid")
deposit_details = deposit_response['data']
# Sample deposit_response:
{
    "success": True,
    "data": {
        "network": "Mumbai",
        "chain_id": 80001,
        "wallet_address": "0x1d6169328e0a2e0a0709115d1860c682cf8d1398",
        "qr_code_data": "ethereum:0x1d6169328e0a2e0a0709115d1860c682cf8d1398@80001"
    }
}

Collection

The collection methods exposed by the sdk are used to retrieve collection details from the Original API.

Get a collection by collection UID

# Get a collection by UID, will throw a 404 Not Found error if the collection does not exist
collection_response = client.get_collection('221137489875')
collection_details = collection_response['data']
# Sample collection_response:
{
    "success": True,
    "data": {
        "uid": "471616646163",
        "name": "Test SDK Collection 1",
        "status": "deployed",
        "type": "ERC721",
        "created_at": "2024-02-13T10:45:56.952745Z",
        "editable_assets": True,
        "contract_address": "0x124a6755ee787153bb6228463d5dc3a02890a7db",
        "symbol": "SYM",
        "description": "Description of the collection",
        "explorer_url": "https://mumbai.polygonscan.com/address/0x124a6755ee787153bb6228463d5dc3a02890a7db"
    }
}

Handling Errors

If something goes wrong, you will receive well typed error messages.

class ClientError(OriginalError): ...
class ServerError(OriginalError): ...
class ValidationError(OriginalError): ...

All errors inherit from an OriginalError class where you can access the standard properties from the Exception class as well as the following:

class OriginalErrorCode(Enum):
    client_error = "client_error"
    server_error = "server_error"
    validation_error = "validation_error"
    

class OriginalError(Exception):
    def __init__(self, message, status, data, code):
        self.message = message
        self.status = status
        self.data = data
        self.code = code.value # 'client_error' | 'server_error' | 'validation_error'
}

So when an error occurs, you can either catch all using the OriginalError class:

from original_sdk import OriginalError

try:
    result = client.create_user('invalid_email', 'client_id');
except OriginalError as e:
    # handle all errors

or specific errors:

from original_sdk import ClientError, ServerError, ValidationError

try:
    result = client.create_user('invalid_email', 'client_id');
except ClientError as e:
    # handle client errors
except ServerError as e:
    # handle server errors
except ValidationError as e:
    # handle validation errors

The error will have this structure:

except OriginalError as error:
    # error.code == 'client_error' | 'server_error' | 'validation_error'
    # error.status == 400 | 404 | ...
    # error.message == 'Not Found' | 'Enter a valid email address.' | ...
    # error.data == { 
    #   "success": False, 
    #   "error": { 
    #       "type": "validation_error", 
    #       "detail": { 
    #           "code": "invalid",
    #           "message": "Enter a valid email address.",
    #           "field_name": "email"
    #        }  
    #    }
    # }

Please note, if you plan to parse the error detail, it can also be an array if there are multiple errors.

    # ...
    # "detail": [
    #     {
    #         "code": "null",
    #         "message": "This field may not be null.",
    #         "field_name": "client_id"
    #     },
    #     {
    #         "code": "invalid",
    #         "message": "Enter a valid email address.",
    #         "field_name": "email"
    #     }
    # ]

If it's a client (SDK) error and not a json response error from our server/REST API, we will return data as a string.

    # "error.data": "Not Found"
    # "error.status": 404
    # "error.code": "client_error"

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

original_sdk-1.2.1.tar.gz (17.6 kB view details)

Uploaded Source

Built Distribution

original_sdk-1.2.1-py3-none-any.whl (15.7 kB view details)

Uploaded Python 3

File details

Details for the file original_sdk-1.2.1.tar.gz.

File metadata

  • Download URL: original_sdk-1.2.1.tar.gz
  • Upload date:
  • Size: 17.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/7.0.1 pkginfo/1.9.6 requests/2.31.0 requests-toolbelt/1.0.0 tqdm/4.66.2 CPython/3.10.13

File hashes

Hashes for original_sdk-1.2.1.tar.gz
Algorithm Hash digest
SHA256 5c9a377604d8346c3d907b250e885e6c97a60e664369a00fc43c1f56a72a7449
MD5 b10d75005a3cbda2fb648cbaf64bd0c1
BLAKE2b-256 7c6ae28d47873f99a995b7a3e28506e1e0a9069e21fe8d1869658d6ab2912116

See more details on using hashes here.

File details

Details for the file original_sdk-1.2.1-py3-none-any.whl.

File metadata

  • Download URL: original_sdk-1.2.1-py3-none-any.whl
  • Upload date:
  • Size: 15.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/7.0.1 pkginfo/1.9.6 requests/2.31.0 requests-toolbelt/1.0.0 tqdm/4.66.2 CPython/3.10.13

File hashes

Hashes for original_sdk-1.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ea614e7a64ddee1d5996ef33a029986490ac95042e55c9293474180e660f044f
MD5 11d7a16434ab537b04f16d151bc26fd0
BLAKE2b-256 3170e6a98112ee0667c324e1f5a780295a133a352590db9953a566d16ff0af42

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page