7 juil. 2024

[Dynamo += Python] Introduction Autodesk Plateforme Services (Partie 2/2)





Suite d'une introduction a l'API Autodesk Plateforme Service directement (APS) depuis Dynamo sur la plateforme ACC

#DynamoBIM #Revit #Python  #APS #ACC        #AutodeskExpertElite #AutodeskCommunity 

if this article is not in your language, use the Google Translate widget ⬈ (bottom of page for Mobile version )


  • Introduction

Dans cet article, nous explorons comment utiliser APS pour améliorer la gestion des projets sur Autodesk Construction Cloud (ACC) à travers Dynamo. Nous aborderons :

    1. Enregistrement et Authentification d'une Application Web :

    • Comment enregistrer une application web et s'authentifier via une application tierce.

    2. Gestion des Données de Projet :

    • Localisation du dossier principal d'un projet sur ACC.
    • Extraction et structuration des données des fichiers Revit en utilisant une DataTable avec .NET ou un DataFrame avec pandas.
    3. Liaison de Maquettes :

    • Technique pour lier des maquettes individuelles à une maquette hôte.

Nous utiliserons dans cet article les API suivantes 
    • Authentification API
    • Data Management API

Dans la suite de cet article, nous utiliserons Dynamo3 + IronPython3 et la librairie .Net Newtonsoft Json.
Vous trouverez en fin d'article un exemple avec CPython3 et la libraire Python json

  • Authentification et Scopes

Vous trouverez sur l'article précédent des informations sur l'authentification 

Nous devons ici définir les 'scopes' suivant  : data:read / data:search/ data:write 


import sys
import clr
import System
from System.Collections.Generic import List, IList, Dictionary

import System.Text;
from System.Text import Encoding

clr.AddReference('Newtonsoft.Json')
import Newtonsoft.Json;
import Newtonsoft.Json.Linq;
from Newtonsoft.Json.Linq import JObject, JArray, JToken

clr.AddReference('System.Net.Http')
import System.Net.Http
from System.Net.Http import *

def get_auth_token(client_id, secret_id):
    b_64_pass = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(client_id + ":" + secret_id))
    token = None
    with HttpClient() as client:
        client.DefaultRequestHeaders.Add("Authorization", "Basic " + b_64_pass)
        parameters = Dictionary[System.String, System.String]()
        parameters.Add("Content-Type", "application/x-www-form-urlencoded")
        parameters.Add("Accept", "application/x-www-form-urlencoded")
        parameters.Add("grant_type", "client_credentials")
        parameters.Add("scope", r"data:read data:write data:search")
        response = client.PostAsync("https://developer.api.autodesk.com/authentication/v2/token", FormUrlEncodedContent(parameters)).Result
        result = response.Content.ReadAsStringAsync().Result
        jobject = JObject.Parse(result)
        token_type = jobject["token_type"]
        token = jobject["access_token"].ToString()
    return token

token = get_auth_token("CLIENT_ID_KEY", "CLIENT_SECRET_KEY")


OUT = token

  • Recherche du projet ACC sur notre Hub

Commençons par la localisation du projet dans Autodesk Construction Cloud (ACC), en identifiant d'abord le hub puis le dossier principal du projet.



import sys
import clr
import System
from System.Collections.Generic import List, IList, Dictionary

import System.Text;
from System.Text import Encoding
clr.AddReference('Newtonsoft.Json')
import Newtonsoft.Json;
import Newtonsoft.Json.Linq;
from Newtonsoft.Json.Linq import JObject, JArray, JToken

clr.AddReference('System.Net.Http')
import System.Net.Http
from System.Net.Http import *

clr.AddReference("System.Core")
clr.ImportExtensions(System.Linq)


def get_auth_token(client_id, secret_id):
    b_64_pass = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(client_id + ":" + secret_id))
    token = None
    with HttpClient() as client:
        client.DefaultRequestHeaders.Add("Authorization", "Basic " + b_64_pass)
        parameters = Dictionary[System.String, System.String]()
        parameters.Add("Content-Type", "application/x-www-form-urlencoded")
        parameters.Add("Accept", "application/x-www-form-urlencoded")
        parameters.Add("grant_type", "client_credentials")
        parameters.Add("scope", r"data:read data:write data:search")
        response = client.PostAsync("https://developer.api.autodesk.com/authentication/v2/token", FormUrlEncodedContent(parameters)).Result
        result = response.Content.ReadAsStringAsync().Result
        jobject = JObject.Parse(result)
        token_type = jobject["token_type"]
        token = jobject["access_token"].ToString()
    return token

def get_request_data_management(url, main_item_id="", type_items_request =""):
    global token
    jobjectA = None
    with HttpClient() as client:
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token)
        response = client.GetAsync(url + main_item_id + type_items_request, HttpCompletionOption.ResponseContentRead).Result
        resultA = response.Content.ReadAsStringAsync().Result
        jobjectA = JObject.Parse(resultA)
        #data_arrayA = JArray(jobjectA["data"])

    return jobjectA

my_hub_name = "MY_HUB_NAME"
my_project_name = "MY_PROJECT_NAME"
# get token
token_type = None
token = get_auth_token("CLIENT_ID_KEY", "CLIENT_SECRET_KEY")
# get hub id
jobject_hubs_data = get_request_data_management("https://developer.api.autodesk.com/project/v1/hubs/")
data_hubs_array = JArray(jobject_hubs_data["data"])
my_hub_id = next((data["id"].ToString() for data in data_hubs_array if data["attributes"]["name"].ToString() == my_hub_name), None)
# get project id
jobject_projects_data = get_request_data_management("https://developer.api.autodesk.com/project/v1/hubs/", my_hub_id, type_items_request ="/projects")
data_array_projects = JArray(jobject_projects_data["data"])
my_project_id = next((data["id"].ToString() for data in data_array_projects if data["attributes"]["name"].ToString() == my_project_name), None)
# get root folder
root_folder_id = next((data["relationships"]["rootFolder"]["data"]["id"].ToString() for data in data_array_projects if data["attributes"]["name"].ToString() == my_project_name), None)
#
OUT = root_folder_id

  • Récupérer les fichiers RVT ainsi que leurs propriétés
Dans le cadre de ce projet ACC, nous cherchons toutes les maquettes Revit et collectons quelques-unes de leurs propriétés.

Ce jeu de données peut être intégré dans une DataTable (.Net) ou un DataFrame avec pandas, permettant ainsi une manipulation et une visualisation des données de projet.

Nous utilisons ici une fonction récursive avec une pause (time.sleep) pour ne pas dépasser le quota de requêtes autorisé.
Vous pouvez utiliser la fonction search si vous utilisez l'authentification en 3 étapes (3-Legged Token).


code complet (2 versions)


import sys
import clr
import System
from System.Collections.Generic import List, IList, Dictionary

import System.Text;
from System.Text import Encoding
clr.AddReference('Newtonsoft.Json')
import Newtonsoft.Json
import Newtonsoft.Json.Linq
from Newtonsoft.Json.Linq import JObject, JArray, JToken
clr.AddReference('System.Collections.Specialized')
import System.Collections.Specialized;

clr.AddReference('System.Data')
from System.Data import *
clr.AddReference('System.Data.DataSetExtensions')
clr.ImportExtensions(System.Data.DataTableExtensions)

clr.AddReference('System.Net.Http')
import System.Net.Http
from System.Net.Http import *

clr.AddReference("System.Core")
clr.ImportExtensions(System.Linq)

my_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments)

import logging
import time
## Start create logger Object ##
logger = logging.getLogger("APSLogger")
# set to  DEBUG
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s :: %(levelname)s :: %(funcName)s :: %(message)s')
# create handler 
file_handler = logging.FileHandler(my_path + '\\APSLogger.log', mode='w')
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.disabled = False


class CustomDataTable(DataTable):
    """A custom DataTable class with additional functionalities"""
    def __new__(cls):
        return super(DataTable, cls).__new__(cls)

    def __init__(self):
        pass
        
    def __repr__(self):
        lst_size = []
        for col in self.Columns:
            max_size_txt = max([len(row[col]) for row in self.Rows] + [len(col.ColumnName) + 1])
            lst_size.append(max_size_txt)
        value = '\t'.join(['{0:{1}}'.format(col.ColumnName, lst_size[idx]) for idx, col in enumerate(list(self.Columns))]) + "\n"
        value += '\n'.join(['\t'.join(['{0:{1}}'.format(x, lst_size[idx]) for idx, x in enumerate(r.ItemArray)]) for r in self.Rows])
        return value

def get_auth_token(client_id, secret_id):
    b_64_pass = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(client_id + ":" + secret_id))
    token = None
    with HttpClient() as client:
        client.DefaultRequestHeaders.Add("Authorization", "Basic " + b_64_pass)
        parameters = Dictionary[System.String, System.String]()
        parameters.Add("Content-Type", "application/x-www-form-urlencoded")
        parameters.Add("Accept", "application/x-www-form-urlencoded")
        parameters.Add("grant_type", "client_credentials")
        parameters.Add("scope", r"data:read data:write data:search")
        response = client.PostAsync("https://developer.api.autodesk.com/authentication/v2/token", FormUrlEncodedContent(parameters)).Result
        result = response.Content.ReadAsStringAsync().Result
        jobject = JObject.Parse(result)
        token = jobject["access_token"].ToString()
    return token

def get_request_data_management(url, main_item_id="", type_items_request =""):
    global token
    jobjectA = None
    with HttpClient() as client:
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token)
        response = client.GetAsync(url + main_item_id + type_items_request, HttpCompletionOption.ResponseContentRead).Result
        resultA = response.Content.ReadAsStringAsync().Result
        jobjectA = JObject.Parse(resultA)
    return jobjectA
    
def get_subItems_data(project_id, folder_id, incr=0):
    # add a sleep to avoid the Quota limit exceeded.
    time.sleep(0.2)
    if incr > 30:
        yield [None, None]
    url = "https://developer.api.autodesk.com/data/v1/projects/"    
    jobject_contents = get_request_data_management(url, project_id, type_items_request ="/folders/{}/contents".format(folder_id))
    for jobject in jobject_contents["data"]:
        content_type = jobject["type"].ToString()
        content_id = jobject["id"].ToString()
        content_name = jobject["attributes"]["displayName"].ToString()
        if content_type == "folders":
            for x_Id, x_Name in  get_subItems_data(project_id, content_id, incr + 1):
                yield [x_Id, x_Name] #[content_name, content_id]
        elif content_type == "items" and content_name.endswith(".rvt"):
            yield [content_id, content_name] #[content_name, content_id]
        else:
            pass
    
out = []
out_dict = {}
my_hub_name = "BE-BIM-SOFLUX"
my_project_name = "00 - Projets_Temp"
# get token
token_type = None
token = get_auth_token("kpZZH0QVgasifQAUz4khFHyih21yQjbV", "dhXSlJVBOIGIU2Bm")
# get hub id
jobject_hubs_data = get_request_data_management("https://developer.api.autodesk.com/project/v1/hubs/")
logger.debug(jobject_hubs_data)
data_hubs_array = JArray(jobject_hubs_data["data"])
my_hub_id = next((data["id"].ToString() for data in data_hubs_array if data["attributes"]["name"].ToString() == my_hub_name), None)
logger.debug(("my_hub_id", my_hub_id))
# get project id
jobject_projects_data = get_request_data_management("https://developer.api.autodesk.com/project/v1/hubs/", my_hub_id, type_items_request ="/projects")
data_array_projects = JArray(jobject_projects_data["data"])
my_project_id = next((data["id"].ToString() for data in data_array_projects if data["attributes"]["name"].ToString() == my_project_name), None)
logger.debug(("my_project_id", my_project_id))
# get root folder
root_folder_id = next((data["relationships"]["rootFolder"]["data"]["id"].ToString() for data in data_array_projects if data["attributes"]["name"].ToString() == my_project_name), None)
logger.debug(("root_folder_id", root_folder_id))
#
# create a DataTable
lst_extract_data = ["urn_id_version", "urn_id", "project_id", "file_name", "project_name", "folder_name", "version_number", "lastModifiedTime", "revit_version", "projectGuid", "modelGuid", "storageSize"]
dt = CustomDataTable()
dt.TableName = "Data Rvt Info"
for colName in lst_extract_data:
    dt.Columns.Add(colName, System.String)
# get all items file
for file_id, file_name in get_subItems_data(my_project_id, root_folder_id):
    logger.debug((file_id, file_name))
    # get parent folder data
    j_parent_folder = get_request_data_management("https://developer.api.autodesk.com/data/v1/projects/" , my_project_id, type_items_request ="/items/{}/parent".format(file_id))
    logger.info("j_parent_folder")
    logger.debug(j_parent_folder)
    folder_name = j_parent_folder["data"]["attributes"]["displayName"].ToString()
    # get all version of this model (rvt)
    jobject_versions = get_request_data_management("https://developer.api.autodesk.com/data/v1/projects/", my_project_id, type_items_request ="/items/{}/versions".format(file_id))
    data_versions_array = JArray(jobject_versions["data"])
    out_dict[file_name] = []
    for idx, j_version in enumerate(data_versions_array):
        logger.info("***j_version***")
        logger.debug(("versionNumber", j_version["attributes"]["versionNumber"].ToString()))
        logger.debug(j_version)
        urn_id_version = j_version["id"].ToString()
        lastModifiedTime = j_version["attributes"]["lastModifiedTime"].ToString()
        versionNumber = j_version["attributes"]["versionNumber"].ToString("0.###")
        storageSize = j_version["attributes"]["storageSize"].ToString() if "storageSize" in j_version["attributes"] else "??"
        j_extension = j_version["attributes"]["extension"]
        try:
            revitProjectVersion = j_extension["data"]["revitProjectVersion"].ToString()
            projectGuid = j_extension["data"]["projectGuid"].ToString()
            modelGuid = j_extension["data"]["modelGuid"].ToString()
        except Exception as ex:
            logger.exception(ex)
            revitProjectVersion = "???"
            projectGuid = "???"
            modelGuid = "???"
        # populate DataTable
        dt.Rows.Add(urn_id_version, file_id, my_project_id, file_name, my_project_name, folder_name, versionNumber, lastModifiedTime, revitProjectVersion, projectGuid, modelGuid, storageSize)

# clear logger
try:
    for handler in logger.handlers:
        if isinstance(handler, logging.FileHandler):
            handler.close()
except:
    for handler in logger.handlers[:]:
        logger.removeHandler(handler)
OUT = repr(dt), 0



# Load the Python Standard and DesignScript Libraries
import sys
import clr
import System
from System.Collections.Generic import List, IList, Dictionary

import System.Text;
from System.Text import Encoding

clr.AddReference('System.Collections.Specialized')
import System.Collections.Specialized;

clr.AddReference('System.Net.Http')
import System.Net.Http
from System.Net.Http import *

clr.AddReference("System.Core")
clr.ImportExtensions(System.Linq)
#
import json
import pandas as pd
pd.set_option('display.max_column', None)
pd.set_option('display.max_rows', None)
pd.set_option('display.max_seq_items', None)
pd.set_option('display.max_colwidth', 500)
pd.set_option('expand_frame_repr', False)

my_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments)

import logging
import time
## Start create logger Object ##
logger = logging.getLogger("APSLogger")
# set to  DEBUG
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s :: %(levelname)s :: %(funcName)s :: %(message)s')
# create handler 
file_handler = logging.FileHandler(my_path + '\\APSLogger.log', mode='w')
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.disabled = False

def get_auth_token(client_id, secret_id):
    b_64_pass = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(client_id + ":" + secret_id))
    token = None
    client = HttpClient()
    client.DefaultRequestHeaders.Add("Authorization", "Basic " + b_64_pass)
    parameters = Dictionary[System.String, System.String]()
    parameters.Add("Content-Type", "application/x-www-form-urlencoded")
    parameters.Add("Accept", "application/x-www-form-urlencoded")
    parameters.Add("grant_type", "client_credentials")
    parameters.Add("scope", r"data:read data:write data:search")
    response = client.PostAsync("https://developer.api.autodesk.com/authentication/v2/token", FormUrlEncodedContent(parameters)).Result
    result = response.Content.ReadAsStringAsync().Result
    jobject = json.loads(result) 
    token = jobject["access_token"]
    client.Dispose()
    return token

def get_request_data_management(url, main_item_id="", type_items_request =""):
    global token
    jobjectA = None
    client = HttpClient()
    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token)
    response = client.GetAsync(url + main_item_id + type_items_request, HttpCompletionOption.ResponseContentRead).Result
    resultA = response.Content.ReadAsStringAsync().Result
    jobjectA = json.loads(resultA) 
    client.Dispose()
    return jobjectA
    
def get_subItems_data(project_id, folder_id, incr=0):
    # add a sleep to avoid the Quota limit exceeded.
    time.sleep(0.2)
    if incr > 30:
        yield [None, None]
    url = "https://developer.api.autodesk.com/data/v1/projects/"    
    jobject_contents = get_request_data_management(url, project_id, type_items_request ="/folders/{}/contents".format(folder_id))
    for jobject in jobject_contents["data"]:
        content_type = jobject["type"]
        content_id = jobject["id"]
        content_name = jobject["attributes"]["displayName"]
        if content_type == "folders":
            for x_Id, x_Name in  get_subItems_data(project_id, content_id, incr + 1):
                yield [x_Id, x_Name] 
        elif content_type == "items" and content_name.endswith(".rvt"):
            yield [content_id, content_name] 
        else:
            pass
    
out = []
out_dict = {}
my_hub_name = "BE-BIM-SOFLUX"
my_project_name = "00 - Projets_Temp"
# get token
token_type = None
token = get_auth_token("kpZZH0QVgasifQAUz4khFHyih21yQjbV", "dhXSlJVBOIGIU2Bm")
# get hub id
jobject_hubs_data = get_request_data_management("https://developer.api.autodesk.com/project/v1/hubs/")
logger.debug(jobject_hubs_data)
data_hubs_array = jobject_hubs_data["data"]
my_hub_id = next((data["id"] for data in data_hubs_array if data["attributes"]["name"] == my_hub_name), None)
logger.debug(("my_hub_id", my_hub_id))
# get project id
jobject_projects_data = get_request_data_management("https://developer.api.autodesk.com/project/v1/hubs/", my_hub_id, type_items_request ="/projects")
data_array_projects = jobject_projects_data["data"]
my_project_id = next((data["id"] for data in data_array_projects if data["attributes"]["name"] == my_project_name), None)
logger.debug(("my_project_id", my_project_id))
# get root folder
root_folder_id = next((data["relationships"]["rootFolder"]["data"]["id"] for data in data_array_projects if data["attributes"]["name"] == my_project_name), None)
logger.debug(("root_folder_id", root_folder_id))
# object With column names only
lst_extract_data = ["urn_id_version", "urn_id", "project_id", "file_name", "project_name", "folder_name", "version_number", "lastModifiedTime", "revit_version", "projectGuid", "modelGuid", "storageSize"]
df = pd.DataFrame(columns = lst_extract_data)
# get all items file
for file_id, file_name in get_subItems_data(my_project_id, root_folder_id):
    logger.debug((file_id, file_name))
    # get parent folder data
    j_parent_folder = get_request_data_management("https://developer.api.autodesk.com/data/v1/projects/" , my_project_id, type_items_request ="/items/{}/parent".format(file_id))
    logger.info("j_parent_folder")
    logger.debug(j_parent_folder)
    folder_name = j_parent_folder["data"]["attributes"]["displayName"]
    jobject_versions = get_request_data_management("https://developer.api.autodesk.com/data/v1/projects/", my_project_id, type_items_request ="/items/{}/versions".format(file_id))
    data_versions_array = jobject_versions["data"]
    out_dict[file_name] = []
    for idx, j_version in enumerate(data_versions_array):
        logger.info("***j_version***")
        logger.debug(("versionNumber", j_version["attributes"]["versionNumber"]))
        logger.debug(j_version)
        urn_id_version = j_version["id"]
        lastModifiedTime = j_version["attributes"]["lastModifiedTime"]
        versionNumber = j_version["attributes"]["versionNumber"]
        storageSize = j_version["attributes"]["storageSize"] if "storageSize" in j_version["attributes"] else "??"
        j_extension = j_version["attributes"]["extension"]
        try:
            revitProjectVersion = j_extension["data"]["revitProjectVersion"]
            projectGuid = j_extension["data"]["projectGuid"]
            modelGuid = j_extension["data"]["modelGuid"]
        except Exception as ex:
            logger.exception(ex)
            revitProjectVersion = "???"
            projectGuid = "???"
            modelGuid = "???"
        # get the current number of rows in DataFrame and use it at index
        n_row = df.shape[0]
        # append dataa to a new row in dataFrame
        df.loc[n_row] = [urn_id_version, file_id, my_project_id, file_name, my_project_name, folder_name, versionNumber, lastModifiedTime, revitProjectVersion, projectGuid, modelGuid, storageSize]

# clear logger
try:
    for handler in logger.handlers:
        if isinstance(handler, logging.FileHandler):
            handler.close()
except:
    for handler in logger.handlers[:]:
        logger.removeHandler(handler)

OUT = repr(df), 0



Note :

Si vous utilisez Dynamo, je recommande fortement d'utiliser un logger pour analyser les réponses des requêtes Web.

L'autre solution étant d'utiliser un notebook Jupiter ou Google Collab avec le module Python request

  • Liaison de modèles à une maquette 
Dans ce dernier exemple, nous allons lier plusieurs maquettes à une maquette hôte, en se référant à cet article du blog APS. 

Nous utilisons identifiants uniques des modèles (URNs) recueillis à partir de la précédente DataTable (voir code précédent) pour établir les liaisons des maquettes.

  1. Depuis la DataTable, nous isolons la maquette qui servira d'hôte et nous vérifions si elle comporte déjà des liens.

  2. Puis, nous effectuons des liaisons en récupérant les urns des maquettes les plus récentes.

    Pour faire cela, nous utilisons pour cela le paramètre copyFrom de la méthode POST
projects/:project_id/versions

    • fonction pour lier des modèles à un modèle hôte ACC

def post_request_link_files(projectId, mainfile_urn, lst_link_urn):
    global token
    response = None
    with HttpClient() as client:
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token)
        lst_xref = []
        for link_urn in lst_link_urn:
            lst_xref.append({
            "type": "versions",
            "id": link_urn,
            "meta": {
                "refType": "xrefs",
                "direction": "from",
                "extension": {
                    "type": "xrefs:autodesk.core:Xref",
                    "version": "1.1",
                    "data": {
                        "nestedType": "overlay"
                            }
                        }
                    }
            })
        content = {
                    "jsonapi": {
                        "version": "1.0"
                    },
                    "data": {
                        "type": "versions",
                        "relationships": {
                            "refs": {  
                                "data": lst_xref
                            }
                        }
                    }
                }
        jsonRequest = Newtonsoft.Json.JsonConvert.SerializeObject(content);
        httpContent = StringContent(jsonRequest, Encoding.UTF8, "application/json")
        url = "https://developer.api.autodesk.com/data/v1/projects/{}/versions?copyFrom={}".format(projectId, mainfile_urn)
        response = client.PostAsync(url, httpContent)
        jsonResponse = response.Result.Content.ReadAsStringAsync().Result
        #print(jsonResponse)
        response_data = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonResponse);
    return response_data

    • code pour le processus de liaison

      1. filtrage de la DataTable
      2. vérification si la maquette contient déjà des liens
      3. appel de la fonction pour établir les liaisons avec les urns en arguments

Note
les caractères spéciaux présents dans les URL ("!*'();:@&=+$,/?%#[]") doivent être encodés.


# filter DataTable by Folder Name
strDataExpression = "[folder_name] = '"+ folder_rvt_models_to_federate + "'"
lstRows = dt.Select(strDataExpression)
# group by rvt name and order by version
lstRows = List[DataRow](lstRows \
                .GroupBy(lambda r : r["file_name"]) \
                .Select(lambda g : g.OrderBy( lambda r : int(r["version_number"])).Last()))
# convert DataRows to new Custom DataTable
newdt = CustomDataTable.DataRows_to_DataTable(lstRows, nameDataTable="RVT")
# get the host Revit model with "00" in rvt file name
filterFunc_Elec = System.Func[DataRow, System.Boolean](lambda row : row["file_name"].startswith("00"))
dataRows_Elec = Enumerable.Where[DataRow]([x for x in newdt.Rows], filterFunc_Elec )
# get the link Revit models with NOT "00" in rvt file name
filterFunc_link = System.Func[DataRow, System.Boolean](lambda row : not row["file_name"].startswith("00"))
dataRows_links = Enumerable.Where[DataRow]([x for x in newdt.Rows], filterFunc_link )
for row_elec in dataRows_Elec:
    urn_id_version_main = row_elec["urn_id_version"]
    # check if there are already relationships
    jobject_relationships_data = get_request_data_management("https://developer.api.autodesk.com/data/v1/projects/", 
                                                             my_project_id, 
                                                             type_items_request ="/versions/{}/relationships/refs".format(HttpUtility.UrlEncode(urn_id_version_main)))
    data_array_relationships = JArray(jobject_relationships_data["data"])
    #
    if len(data_array_relationships) == 0:
        lst_link_urn_id_version = [r["urn_id_version"] for r in dataRows_links]
        result = post_request_link_files(my_project_id, HttpUtility.UrlEncode(urn_id_version_main), lst_link_urn_id_version)

Quelques Ressources


0 commentaires:

Enregistrer un commentaire