From 7da3d9ee70969d6bae270539b4c422f8748945fd Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Wed, 7 Dec 2022 12:20:29 +1100 Subject: [PATCH] Add docs for library API module --- .../ifcopenshell/api/library/add_library.py | 42 +++++++++++++++++-- .../ifcopenshell/api/library/add_reference.py | 36 +++++++++++++--- .../api/library/assign_reference.py | 38 ++++++++++++++--- .../ifcopenshell/api/library/edit_library.py | 25 +++++++++-- .../api/library/edit_reference.py | 26 ++++++++++-- .../api/library/remove_library.py | 21 ++++++++-- .../api/library/remove_reference.py | 23 ++++++++-- .../api/library/unassign_reference.py | 37 ++++++++++++++-- 8 files changed, 213 insertions(+), 35 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/add_library.py b/src/ifcopenshell-python/ifcopenshell/api/library/add_library.py index e7cc867970..15ab4a78b2 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/library/add_library.py +++ b/src/ifcopenshell-python/ifcopenshell/api/library/add_library.py @@ -22,11 +22,45 @@ import ifcopenshell.util.date class Usecase: - def __init__(self, file, **settings): + def __init__(self, file, name=None): + """Adds a new library to the project + + A library is an external data source that is related to the project. It + may be a database, a spreadsheet, an API, or even a stack of papers in a + filing cabinet. This allows IFC data to store relationships to these + external data sources. + + For example, you may have a list of laser scans of a site stored in an + online platform, which can be queried using an API. Or, you might have a + database of live building sensor data. So long as there is a clear + identifier you can use to link the two datasets together, you can create + a relationship. + + Note that IFC does not store any instructions on how to access the + library. It does not specify whether a HTTP request or database + connection needs to be made or what protocol the library operates with. + Until this is fleshed out further, it is the users responsibility to + name the libraries consistently and use appropriate identifiers. For + example, if you are linking IFC data and Brickschema data, use a full + URI for the identifier with no abbreviation (e.g. + 'http://example.org/digitaltwin#AHU01', not 'digitaltwin:AHU01'). + + A library will then contain a list of references within that library. + These references will then be related to IFC elements. For example, a + library will represent an external database, and a reference will point + to a particular table and row within that database. + + :param name: The name of the library + :type name: str + :return: The newly created IfcLibraryInformation + :rtype: ifcopenshell.entity_instance.entity_instance + + Example:: + + ifcopenshell.api.run("library.add_library", model, name="Brickschema") + """ self.file = file - self.settings = {"name": None} - for key, value in settings.items(): - self.settings[key] = value + self.settings = {"name": name} def execute(self): return self.file.create_entity("IfcLibraryInformation", Name=self.settings["name"]) diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/add_reference.py b/src/ifcopenshell-python/ifcopenshell/api/library/add_reference.py index c504db19ad..32e8638dbe 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/library/add_reference.py +++ b/src/ifcopenshell-python/ifcopenshell/api/library/add_reference.py @@ -16,17 +16,41 @@ # You should have received a copy of the GNU Lesser General Public License # along with IfcOpenShell. If not, see . -import ifcopenshell - class Usecase: - def __init__(self, file, **settings): + def __init__(self, file, library=None): + """Adds a new reference to a library + + A library represents an external data source, such as a database, + spreadsheet, API, or something else that contains information related to + the IFC project. Within a library, there will be one or more references, + such as reference to a particular table or row in a database, or a sheet + and row or column in a spreadsheet, a URI in a linked data Brickschema + file, 32-bit decimal BACnetObjectIdentifier in a BACnet system, IP + address in a network, and so on. + + These references can then be related to IFC elements. You cannot relate + an IFC element directly to a library, it must be related to one of the + library's references. + + :param library: The IfcLibraryInformation element to add a reference to + :type library: ifcopenshell.entity_instance.entity_instance + :return: The newly created IfcLibraryReference element + :rtype: ifcopenshell.entity_instance.entity_instance + + Example:: + + library = ifcopenshell.api.run("library.add_library", model, name="Brickschema") + + # Let's create a reference to a single AHU in our Brickschema dataset + reference = ifcopenshell.api.run("library.add_reference", model, library=library) + ifcopenshell.api.run("library.edit_reference", model, + reference=reference, attributes={"Identification": "http://example.org/digitaltwin#AHU01"}) + """ self.file = file self.settings = { - "library": None, + "library": library, } - for key, value in settings.items(): - self.settings[key] = value def execute(self): if self.file.schema == "IFC2X3": diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/assign_reference.py b/src/ifcopenshell-python/ifcopenshell/api/library/assign_reference.py index 563acc99e3..b5b55ecbd5 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/library/assign_reference.py +++ b/src/ifcopenshell-python/ifcopenshell/api/library/assign_reference.py @@ -20,14 +20,42 @@ import ifcopenshell class Usecase: - def __init__(self, file, **settings): + def __init__(self, file, product=None, reference=None): + """Associates a product with a library reference + + A product may be associated with zero, one, or many references across + multiple libraries. See ifcopenshell.api.library.add_reference for more + detail about how references work. + + :param product: The IfcProduct you want to associate with the reference + :type product: ifcopenshell.entity_instance.entity_instance + :param reference: The IfcLibraryReference you want the product to be + associated with. + :type reference: ifcopenshell.entity_instance.entity_instance + :return: The IfcRelAssociatesLibrary relationship entity + :rtype: ifcopenshell.entity_instance.entity_instance + + Example:: + + library = ifcopenshell.api.run("library.add_library", model, name="Brickschema") + + # Let's create a reference to a single AHU in our Brickschema dataset + reference = ifcopenshell.api.run("library.add_reference", model, library=library) + ifcopenshell.api.run("library.edit_reference", model, + reference=reference, attributes={"Identification": "http://example.org/digitaltwin#AHU01"}) + + # Let's assume we have an AHU in our model. + ahu = ifcopenshell.api.run("root.create_entity", model, + ifc_class="IfcUnitaryEquipment", predefined_type="AIRHANDLER") + + # And now assign the IFC model's AHU with its Brickschema counterpart + ifcopenshell.api.run("library.assign_reference", model, reference=reference, product=ahu) + """ self.file = file self.settings = { - "product": None, - "reference": None, + "product": product, + "reference": reference, } - for key, value in settings.items(): - self.settings[key] = value def execute(self): if self.file.schema == "IFC2X3": diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/edit_library.py b/src/ifcopenshell-python/ifcopenshell/api/library/edit_library.py index b64256d6db..ba563b1d11 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/library/edit_library.py +++ b/src/ifcopenshell-python/ifcopenshell/api/library/edit_library.py @@ -18,11 +18,28 @@ class Usecase: - def __init__(self, file, **settings): + def __init__(self, file, library=None, attributes=None): + """Edits the attributes of an IfcLibraryInformation + + For more information about the attributes and data types of an + IfcLibraryInformation, consult the IFC documentation. + + :param library: The IfcLibraryInformation entity you want to edit + :type library: ifcopenshell.entity_instance.entity_instance + :param attributes: a dictionary of attribute names and values. + :type attributes: dict, optional + :return: None + :rtype: None + + Example:: + + library = ifcopenshell.api.run("library.add_library", model, name="Brickschema") + ifcopenshell.api.run("library.edit_library", model, library=library, + attributes={"Description": "A Brickschema TTL including only mechanical distribution systems."}) + """ + self.file = file - self.settings = {"library": None, "attributes": {}} - for key, value in settings.items(): - self.settings[key] = value + self.settings = {"library": library, "attributes": attributes or {}} def execute(self): for name, value in self.settings["attributes"].items(): diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/edit_reference.py b/src/ifcopenshell-python/ifcopenshell/api/library/edit_reference.py index 342b1fbad2..733fb81cd7 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/library/edit_reference.py +++ b/src/ifcopenshell-python/ifcopenshell/api/library/edit_reference.py @@ -18,11 +18,29 @@ class Usecase: - def __init__(self, file, **settings): + def __init__(self, file, reference=None, attributes=None): + """Edits the attributes of an IfcLibraryReference + + For more information about the attributes and data types of an + IfcLibraryReference, consult the IFC documentation. + + :param reference: The IfcLibraryReference entity you want to edit + :type reference: ifcopenshell.entity_instance.entity_instance + :param attributes: a dictionary of attribute names and values. + :type attributes: dict, optional + :return: None + :rtype: None + + Example:: + + library = ifcopenshell.api.run("library.add_library", model, name="Brickschema") + # Let's create a reference to a single AHU in our Brickschema dataset + reference = ifcopenshell.api.run("library.add_reference", model, library=library) + ifcopenshell.api.run("library.edit_reference", model, + reference=reference, attributes={"Identification": "http://example.org/digitaltwin#AHU01"}) + """ self.file = file - self.settings = {"reference": None, "attributes": {}} - for key, value in settings.items(): - self.settings[key] = value + self.settings = {"reference": reference, "attributes": attributes or {}} def execute(self): for name, value in self.settings["attributes"].items(): diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/remove_library.py b/src/ifcopenshell-python/ifcopenshell/api/library/remove_library.py index 3c2f671408..47c72c183e 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/library/remove_library.py +++ b/src/ifcopenshell-python/ifcopenshell/api/library/remove_library.py @@ -18,11 +18,24 @@ class Usecase: - def __init__(self, file, **settings): + def __init__(self, file, library=None): + """Removes a library + + All references along with their relationships will also be removed. Any + products which have relationships to this library will not be removed. + + :param library: The IfcLibraryInformation entity you want to remove + :type library: ifcopenshell.entity_instance.entity_instance + :return: None + :rtype: None + + Example:: + + library = ifcopenshell.api.run("library.add_library", model, name="Brickschema") + ifcopenshell.api.run("library.remove_library", model, library=library) + """ self.file = file - self.settings = {"library": None} - for key, value in settings.items(): - self.settings[key] = value + self.settings = {"library": library} def execute(self): for reference in set(self.settings["library"].HasLibraryReferences or []): diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/remove_reference.py b/src/ifcopenshell-python/ifcopenshell/api/library/remove_reference.py index 4a5199d7d9..b106954165 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/library/remove_reference.py +++ b/src/ifcopenshell-python/ifcopenshell/api/library/remove_reference.py @@ -18,11 +18,26 @@ class Usecase: - def __init__(self, file, **settings): + def __init__(self, file, reference=None): + """Removes a library reference + + Any products which have relationships to this reference will not be + removed. + + :param reference: The IfcLibraryReference entity you want to remove + :type reference: ifcopenshell.entity_instance.entity_instance + :return: None + :rtype: None + + Example:: + + library = ifcopenshell.api.run("library.add_library", model, name="Brickschema") + reference = ifcopenshell.api.run("library.add_reference", model, library=library) + # Let's change our mind and remove it. + ifcopenshell.api.run("library.remove_reference", model, reference=reference) + """ self.file = file - self.settings = {"reference": None} - for key, value in settings.items(): - self.settings[key] = value + self.settings = {"reference": reference} def execute(self): for rel in self.settings["reference"].LibraryRefForObjects: diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/unassign_reference.py b/src/ifcopenshell-python/ifcopenshell/api/library/unassign_reference.py index 2563abeb8c..d8db411d07 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/library/unassign_reference.py +++ b/src/ifcopenshell-python/ifcopenshell/api/library/unassign_reference.py @@ -18,11 +18,40 @@ class Usecase: - def __init__(self, file, **settings): + def __init__(self, file, reference=None, product=None): + """Unassigns a product from a reference + + If the product isn't assigned to the reference, nothing will happen. + + :param reference: The IfcLibraryReference to unassign from + :type reference: ifcopenshell.entity_instance.entity_instance + :param product: A IfcProduct element to unassign from the reference + :type product: ifcopenshell.entity_instance.entity_instance + :return: None + :rtype: None + + Example:: + + library = ifcopenshell.api.run("library.add_library", model, name="Brickschema") + + # Let's create a reference to a single AHU in our Brickschema dataset + reference = ifcopenshell.api.run("library.add_reference", model, library=library) + ifcopenshell.api.run("library.edit_reference", model, + reference=reference, attributes={"Identification": "http://example.org/digitaltwin#AHU01"}) + + # Let's assume we have an AHU in our model. + ahu = ifcopenshell.api.run("root.create_entity", model, + ifc_class="IfcUnitaryEquipment", predefined_type="AIRHANDLER") + + # And now assign the IFC model's AHU with its Brickschema counterpart + ifcopenshell.api.run("library.assign_reference", model, reference=reference, product=ahu) + + # Let's change our mind and unassign it. + ifcopenshell.api.run("library.unassign_reference", model, reference=reference, product=ahu) + """ + self.file = file - self.settings = {"reference": None, "product": None} - for key, value in settings.items(): - self.settings[key] = value + self.settings = {"reference": reference, "product": product} def execute(self): rels = self.settings["reference"].LibraryRefForObjects