UNSOLVED Trying to get the real path of an Asset Browser url

Asset Browser texture paths are not file system paths and come in an obfuscated format like this:

asset:///file_65161321321e59b~.jpg

Is there a way to get the actual absolute system path of asset:/// or assetdb:/// urls via scripting using the python api? if not, the c++ api?

Seems to be a basic thing that should be really easy to do but I can't find an obvious way.

Thanks!

Hello @byoneukp,

welcome to the Plugin Café and thank you for reaching out to us. The Asset Metadata: Access Asset Description Data goes over some of the details regarding asset URLs. There is also a Python version of that example, but it is not as extensive and leaves out some of the finer details of asset URLs.

Is there a way to get the actual absolute system path of asset:/// or assetdb:/// urls via scripting using the python api?

The answer is sort of yesn't to that. The Asset API is effectively a DBMS and it puts an abstraction layer on its content. Just as for a "normal" DBMS, an item is not meant to be resolved to its physical location because it is the very purpose of the DBMS to abstract that.

I am not quite sure what you mean by system path, but I assume you mean a path on the local machine or network. The vast majority of assets accessible in the Asset Browser of the average user are not stored locally but live either on a Maxon webserver or are builtin assets as for example node templates. It is only the assets which have been created by the user him/herself and assets which have been cached which will be reflected in a local copy.

Furthermore, when a user drags the file 'my_texture.jpg' into the Asset Browser, no file 'my_texture.jpg' will ever be stored. Instead a file 'asset.jpg' will be stored, with metadata expressing that it should be displayed as 'my_texture.jpg' in the Asset Browser. The location of an asset is stored in its URL, there are however three URLs associated with assets.

The raw asset URL accessible with maxon::AssetDescriptionInterface::GetUrl(), where the scheme of that URL will depend on the asset type, but most of the time it will be a ramdisk URL. Ramdisk is a custom URL scheme of the maxon API to abstract the difference between local and remote files. It is the closest thing to what you are looking for. An example would be:

"ramdisk://A9C0F37BAE5146F2/file_3b194acc5a745a2c/1/asset.jpg"

which follows the pattern:

 scheme://repository_id/asset_id/asset_version/asset_file.ext

The last three components of that URL, file_3b194acc5a745a2c/1/asset.jpg in this case, will reflect the physical location of the asset in a local database if the asset does already exist in such database. E.g., the asset file could be stored under C://mydb/file_3b194acc5a745a2c/1/asset.jpg. There are technically ways to resolve the information for C://mydb/ from the repository identifier A9C0F37BAE5146F2, but this is not intended and therefore out of scope of support. As stated in the docs, you should not touch the raw URL as a common user. If you want to save the asset 'outside' of the logic of the Asset API, simply load the asset and then save that content into a new file with the asset name as the file name.

Then there are also the asset URL, retrievable with maxon::AssetInterface::GetAssetUrl, and the human readable asset URL, which can be generated with maxon::UrlInterface::ConvertToUiNameWithRepository. The former will come in the asset URL scheme and is the URL you should use when you want to reference the asset location within Cinema 4D. The latter is actually not a URL but a string and follows the assetdb:// scheme. It is used to display asset URLs in a manner which is meaningful to humans, but it has no meaning for the maxon and Asset API, it is just a display label.

As stated earlier, the answer to your question is yesn't. There is no meaningful answer for a "system path" for each asset, and for the cases where is one, you should not access it anyways. The only reason I can think of why you would want to do this, is to gain write access to the raw asset files. Which is definitely not something you should do, as you could corrupt the whole asset database in the process. If you just want to read an asset, use the examples for loading assets and then optionally save that data to a new location outside of the Asset API.

There also the Asset Databases and Asset Metadata articles in the Asset API Handbook which go over some details of the Asset API architecture I have glanced over here. The Asset API is not an assortment of files on disk which is directly reflected into Cinema 4D, as it was more or less the case with the old Content Browser.

Cheers,
Ferdinand

Thanks, got it to work. Snippet I'm using:

def getPathFromAsset(asset):
    repository = maxon.AssetInterface.GetUserPrefsRepository()
    assetId = maxon.Id(asset)
    assetDescription = repository.FindLatestAsset(maxon.AssetTypes.File(), assetId, maxon.Id(), maxon.ASSET_FIND_MODE.LATEST)
    return assetDescription.GetUrl()

print(getPathFromAsset("file_e55289b63600ab3c"))