Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Recent
    • Tags
    • Users
    • Register
    • Login

    Finding out the latest asset version number/string via python

    Scheduled Pinned Locked Moved Cinema 4D SDK
    python2026
    6 Posts 2 Posters 54 Views 2 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • M Offline
      MPB
      last edited by

      Hi! I'm currently trying to get the latest version of an asset in the asset browser. At first, I thought it should work with "assetDescription.GetVersion()", but that only gives me some kind of ID. The same goes for "GetIdAndVersion()".

      Maybe someone here has an idea on how to get the latest asset version number (or string) in python?

      Cheers!
      MPB

      ferdinandF 1 Reply Last reply Reply Quote 0
      • ferdinandF Offline
        ferdinand @MPB
        last edited by ferdinand

        Hello @MPB,

        Welcome to the Maxon developers forum and its community, it is great to have you with us!

        Getting Started

        Before creating your next postings, we would recommend making yourself accustomed with our forum and support procedures. You did not do anything wrong, we point all new users to these rules.

        • Forum Overview: Provides a broad overview of the fundamental structure and rules of this forum, such as the purpose of the different sub-forums or the fact that we will ban users who engage in hate speech or harassment.
        • Support Procedures: Provides a more in detail overview of how we provide technical support for APIs here. This topic will tell you how to ask good questions and limits of our technical support.
        • Forum Features: Provides an overview of the technical features of this forum, such as Markdown markup or file uploads.

        It is strongly recommended to read the first two topics carefully, especially the section Support Procedures: How to Ask Questions.

        About your First Question

        Without your code and the asset you are trying to read, helping youn concretely is impossible. Asset versioning is demonstrated pretty throughly in this code example.

        I think your major misconception is that an asset version string has to be what you would consider a version descriptor, .e.g., "1.0". But that is absolutely not the case, and you can put there anything you want. The system will by default put there hashes; which is probably what you mean with "some kind of ID".

        You must evaluate the date of last modification of each version of an asset to temporally order them. But that is all not really necessary when you just want to get the last version of an asset, as that is already baked into search operations with maxon.ASSET_FIND_MODE.LATEST. I.e., when you have either an asset ID or an asset description, you just search for that asset ID and set the find mode to latest. See this example for a concrete case.

        You can also search for all versions of an asset and then sort them yourself via the time stamp (see also first example link). You can also access the other versions of an asset if you have just one asset description, as each asset links to its other versions with a list of asset-id-version tuples.

        Cheers,
        Ferdinand

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • M Offline
          MPB
          last edited by

          Hi Ferdinant,

          I'm very sorry for not thinking more about my post. Yes, the devil is in the details: I'm trying to access the version description and - if possible - counting it up +0.1 for the automatic upload of a new version of the asset.

          Here is part of my code as an example, although it's just a proof of concept at the moment. I've added some comments for clarification.

          def process_object(obj, doc, repo, target_category_id, force_new_id=False): #creating a new asset and using the commentary-tag to store asset information
              tag = obj.GetTag(c4d.Tannotation) or obj.MakeTag(c4d.Tannotation)
              tag.SetName(TAG_NAME)
              tag[c4d.ANNOTATIONTAG_TEXT] = obj.GetName()
          
              existing_id_str = tag[c4d.ANNOTATIONTAG_URL] #using the URL-field for the asset-id
              asset_id = None
              if existing_id_str and not force_new_id:
                  try:
                      temp_id = maxon.Id(existing_id_str)
                      
                      #check if the asset-ID is in the database
                      asset_desc = repo.FindLatestAsset(maxon.AssetTypes.File().GetId(), temp_id, maxon.Id(), maxon.ASSET_FIND_MODE.LATEST)
                      if not asset_desc.IsNullValue(): #if the asset is found....
                          asset_id = temp_id  #...use the temp ID as the current ID
                          
                          #get latest version description and try to set the version number +0.1
                          print(asset_desc.GetVersion())
                          print(asset_desc.GetRepositoryId())
                          print(asset_desc.GetMetaData())
                          current_version_str = str(asset_desc.GetVersion()) # <--- this is the tricky part --- 
                          if current_version_str:
                              try:
                                  current_version = float(current_version_str) + 0.1 #try to convert it to float and add 0.1
                              except ValueError:
                                  current_version = 1.0 #...if unsuccessful (string that shouldn't be used), then start with 1.0 again
                          else: #if none
                              current_version = 1.0
          .....
          

          I hope this makes sense.
          Thank you very much for any help!

          ferdinandF 1 Reply Last reply Reply Quote 0
          • ferdinandF Offline
            ferdinand @MPB
            last edited by ferdinand

            Hey,

            as I already explained, maxon.ASSET_FIND_MODE.LATEST ensures that you find the last version of an asset. So this line of yours:

            asset_desc = repo.FindLatestAsset(maxon.AssetTypes.File().GetId(), temp_id, maxon.Id(), maxon.ASSET_FIND_MODE.LATEST)
            

            will retrieve the last asset version of an asset with the ID temp_id which is of asset type File. If you would use maxon.ASSET_FIND_MODE.ALL for example and then also not FindLatestAsset but FindAssets, you would find all assets that have the ID temp_id.

            The id of an asset is not necessarily unique within a repository. It shares its ID with all other versions of that asset. Only the ID and version can uniquely identify an asset. And as said before, the version of an asset does not have to be a (quasi) numeric value as you assume it to be. The asset version is always a string, and in some cases, for example in the code example I linked to above, people put there something that could be parsed into a numeric value. But the asset version can also just be the string 'Bob's your uncle' or just some hash. So, you cannot sort assets temporally by their asset version. It is just another identifier that makes that version unique within the namespace of the asset ID.

            If you want to temporally sort asset versions, first search for all assets with that ID, and then sort them using their timestamp. This, asset versioning, time stamps and other asset metadata, all has been extensively covered in the code example I already linked to above. Please read the example.

            Cheers,
            Ferdinand

            https://github.com/Maxon-Computer/Cinema-4D-Python-API-Examples/blob/master/scripts/05_modules/assets/asset_metadata_r26.py

            MAXON SDK Specialist
            developers.maxon.net

            1 Reply Last reply Reply Quote 0
            • M Offline
              MPB
              last edited by

              Thank you Ferdinand,

              ok, but how do I get the string of the asset version? I cannot find any reference to the version string in the examples from "asset_metadata_r26.py". I've also searched the SDK and the Asset Framework, but couldn't find anything that would point me in the right direction.

              Or is it not possible to print out the string of a asset-version?

              Really sorry for the inconvenience.

              ferdinandF 1 Reply Last reply Reply Quote 0
              • ferdinandF Offline
                ferdinand @MPB
                last edited by ferdinand

                Hey @MPB,

                there is no need to be sorry, sometimes one struggles even with very on the nose information. But the example is quite verbose, as it contains literally the words "version" and "timestamp" multiple times and explains how these concepts work.

                But it is pointless to endlessly discuss this, it is quicker for me to just write what you want. Here is an example doing exactly what you want to do. Please understand that it is an exception that I write a code example when there is already an example which already explains the subject sufficiently as it is here the case.

                Cheers,
                Ferdinand

                Result

                What we also learn from this, is that the asset team works at unholy hours 😄 .

                Latest version of asset file_266f97c45ea05f17 has version string '2.0.2 - 2022-07-30 02:29', version hash '4905fdf9a02aa951e0d18a6d07f244172a41205a4692b4ae065d6b856e5de7cb' and timestamp '2022-07-30 00:29:28'.
                
                Found 4 asset versions for asset id file_266f97c45ea05f17:
                Found asset version with version string '2.0.2 - 2022-07-30 02:29', version hash '4905fdf9a02aa951e0d18a6d07f244172a41205a4692b4ae065d6b856e5de7cb' and timestamp '2022-07-30 00:29:28'.
                Found asset version with version string '2.0.1 - 2022-02-03 23:45', version hash '3997955fa22c74286c9319509eeaa7a5dccd0230951b608fe338741bbce0d9f9' and timestamp '2022-02-03 22:45:45'.
                Found asset version with version string '2.0.0 - 2022-02-03 23:26', version hash '310c1a6684d8be9eafff1708225b64fe72bff46bd7fae8fa783c39fac7c70d43' and timestamp '2022-02-03 22:26:39'.
                Found asset version with version string '1.0.1 - 2022-02-02 03:02', version hash '5fafa425cbd3f951d4ce8859fc02f51857342094dd0c2fcac8eb4377b7cea9dd' and timestamp '2022-02-02 02:02:47'.
                
                Assets sorted by timestamp:
                file_266f97c45ea05f17/5fafa425cbd3f951d4ce8859fc02f51857342094dd0c2fcac8eb4377b7cea9dd (1.0.1 - 2022-02-02 03:02)
                file_266f97c45ea05f17/310c1a6684d8be9eafff1708225b64fe72bff46bd7fae8fa783c39fac7c70d43 (2.0.0 - 2022-02-03 23:26)
                file_266f97c45ea05f17/3997955fa22c74286c9319509eeaa7a5dccd0230951b608fe338741bbce0d9f9 (2.0.1 - 2022-02-03 23:45)
                file_266f97c45ea05f17/4905fdf9a02aa951e0d18a6d07f244172a41205a4692b4ae065d6b856e5de7cb (2.0.2 - 2022-07-30 02:29)
                

                Code

                #coding: utf-8
                """Provides an example for sorting assets by their time stamp metadata.
                """
                __version__ = "2026.X.X"
                
                import c4d
                import maxon
                
                def main() -> None:
                    """Runs the example for reading asset metadata.
                    """
                    # Get the user preferences repository.
                    repo: maxon.AssetRepositoryRef = maxon.AssetInterface.GetUserPrefsRepository()
                    if not repo:
                        raise RuntimeError("Could not access the user preferences repository.")
                
                    # The id of the "Stone 01" asset which naturally has four asset versions.
                    aid: maxon.Id = maxon.Id("file_266f97c45ea05f17")
                
                    # Find explicitly the latest version of the asset.
                    asset: maxon.AssetDescription = repo.FindLatestAsset(
                        maxon.AssetTypes.File(), aid, maxon.Id(), maxon.ASSET_FIND_MODE.LATEST)
                    
                    # Get the time stamp and version hash and string of the latest asset version.
                    metadata: maxon.AssetMetaData = asset.GetMetaData()
                    timestamp: str = metadata.Get(maxon.ASSETMETADATA.ASSET_TIMESTAMP)
                    version_hash: str = asset.GetVersion()
                    version_string: str = maxon.AssetInterface.GetVersionString(asset)
                
                    print(f"Latest version of asset {aid} has version string '{version_string}', "
                          f"version hash '{version_hash}' and timestamp '{timestamp}'.")
                
                    # Now find all versions of assets with the id #aid and print their metadata.
                    assets: list[maxon.AssetDescription] = repo.FindAssets(
                        maxon.AssetTypes.File(), aid, maxon.Id(), maxon.ASSET_FIND_MODE.ALL)
                    
                    print(f"\nFound {len(assets)} asset versions for asset id {aid}:")
                    for item in assets:
                        metadata = item.GetMetaData()
                        timestamp = metadata.Get(maxon.ASSETMETADATA.ASSET_TIMESTAMP)
                        version_hash = item.GetVersion()
                        version_string = maxon.AssetInterface.GetVersionString(item)
                
                        print(f"Found asset version with version string '{version_string}', "
                              f"version hash '{version_hash}' and timestamp '{timestamp}'.")
                        
                    # So, if we wanted to temporally sort #assets, we could do this. The asset version is naturally
                    # a hash, and there is no grantee that there is a version string or that that string is parsable
                    # into a numeric value which could be sorted.
                    assets.sort(key=lambda a: a.GetMetaData().Get(maxon.ASSETMETADATA.ASSET_TIMESTAMP))
                    print("\nAssets sorted by timestamp:")
                    for item in assets:
                        print(f"{item} ({maxon.AssetInterface.GetVersionString(item)})")
                
                
                if __name__ == "__main__":
                    main()
                

                MAXON SDK Specialist
                developers.maxon.net

                1 Reply Last reply Reply Quote 0
                • First post
                  Last post