Package: aas2openapi
aas2openapi - Middleware for Asset Administration Shell and openAPI 3.0aas2openapi is a middleware for Asset Administration Shell (AAS) and openAPI 3.0. It can be used to transform AAS to openAPI 3.0 objects and vice versa. Moreover, it can be used to generate a CRUD server that allows to access the AAS data via RESTful API with openAPI Specifications.InstallationYou can install the package using by running the following command in the terminal:pipinstallaas2openapiAlternatively, you can install the package withpoetryfor development:poetryshell
poetryinstallPlease note that the package is only compatible with Python 3.10 or higher.Getting startedIn the following, we will consider a minimal example to demonstrate the usage of the package. The example is also available in theexamplesand consists of defining a simple model of an AAS with two submodels, transforming this model and integrating it with the aas2openapi middleware.Defining a simple AASAt first, we create a simple data model with the basic building blocks (AAS and Submodel) of aas2openapi:classBillOfMaterialInfo(models.SubmodelElementCollection):manufacterer:strproduct_type:strclassBillOfMaterial(models.Submodel):components:typing.List[str]bill_of_material_info:BillOfMaterialInfoclassProcessModel(models.Submodel):processes:typing.List[str]classProduct(models.AAS):bill_of_material:BillOfMaterialprocess_model:typing.Optional[ProcessModel]The data model consists of a product that has a process model and a bill of material. The process model and the bill of material are submodels that contain a list of processes and components, respectively. To be able to instantiate an AAS, we also create an instance of this data model:example_product=Product(id="Product1",process_model=ProcessModel(id="PMP1",processes=["join","screw"],semantic_id="PMP1_semantic_id",),bill_of_material=BillOfMaterial(id="BOMP1",components=["stator","rotor","coil","bearing"],semantic_id="BOMP1_semantic_id",bill_of_material_info=BillOfMaterialInfo(id_short="BOMInfoP1",semantic_id="BOMInfoP1_semantic_id",manufacterer="Bosch",product_type="A542",)),)Transforming the AAS to openAPINow, we can useaas2openapito transform the object to an AAS and serialize it with basyx to JSON:importaas2openapiobj_store=aas2openapi.convert_pydantic_model_to_aas(example_product)importbasyx.aas.adapter.json.json_serializationwithopen("examples/simple_aas_and_submodels.json","w",encoding="utf-8")asjson_file:basyx.aas.adapter.json.write_aas_json_file(json_file,obj_store)Of course, we can also transform AAS to python objects, which can be easily transformed to openAPI objects with the middleware:data_model=aas2openapi.convert_object_store_to_pydantic_models(obj_store)print(data_model)Using the aasopenapi middlewareThe aas2openapi middleware is build with fastAPI and generates therefore automatically a openAPI Specification for provided models. To use the middleware, we can simply input our predefined data models and connect it with running basyx servers. Here, we use instances of the data models that we have defined before and create a CRUD RESTful API for them:fromaas2openapi.middlewareimportMiddlewaremiddleware=Middleware()middleware.load_pydantic_model_instances([example_product])middleware.generate_rest_api()middleware.generate_graphql_api()middleware.generate_model_registry_api()app=middleware.appWe can run this app either from the command line with uvicorn:uvicornapp:app--reloadHere, it is assumed, that the file you saved is called app.py. If it has a different name, rename the first app. Alternatively, you can also run the app directly with python, by extending the script at the bottom with:if__name__=="__main__":importuvicornuvicorn.run(app)You can access now the documentation of the REST API with swagger athttp://localhost:8000/docsand the graphql endpoint athttp://localhost:8000/graphql.Besides loading the data models from instances,  we can also generate it directly from its python type, from a JSON-object or from an AAS. To do so, simply replace theload_pydantic_model_instancesmethod withload_pydantic_modelsto load from types orload_aas_objectstoreto load from an AAS object store orload_json_modelsto load from serialized JSON-objects:middleware.load_pydantic_model_types([Product])middleware.load_aas_from_objectstore(obj_store)middleware.load_json_models(file_path="examples/example_json_model.json")However, no examples can be provided when loading from types.We can either run the middleware now directly with python or make a docker build. In both scenarios, an AAS and Submodel-server need to be running that the middleware can connect to. Each request to the middleware is then translated and forwarded to the AAS and Submodel-server.The repository already comes with a docker-compose file that can be used to start the AAS and Submodel-server. To start the docker-compose file, run the following command in the terminal:docker-compose-fdocker-compose-dev.yamlupWe can now run the middleware script with python and access it athttp://localhost:8000/. Documentation of the generated Rest API is athttp://localhost:8000/docsavailable by a swaggerUI and the openAPI Specification is available athttp://localhost:8000/openapi.json. You can use the swaggerUI to post some AAS or this exemplary command (with bash console):curl-X'POST'\'http://127.0.0.1:8000/Product/'\-H'accept: application/json'\-H'Content-Type: application/json'\-d'{"id_short": "Product1","description": "string","id": "Product1","bill_of_material": {"id_short": "BOMP1","description": "","id": "BOMP1","semantic_id": "BOMP1_semantic_id","components": ["stator","rotor","coil","bearing"],"bill_of_material_info": {"id_short": "BOMInfoP1","description": "","semantic_id": "BOMInfoP1_semantic_id","manufacterer": "Bosch","product_type": "A542"}},"process_model": {"id_short": "PMP1","description": "","id": "PMP1","semantic_id": "PMP1_semantic_id","processes": ["join","screw"]}}'If you want to change the adresses and ports of the AAS and Submodel-server, you can do so by adding a.envfile to the root directory of the package. The file should contain speicifications similar to that in the.env.examplefile of the package.Lastly, we can build a docker image of the middleware and run it in a docker-compose as a container. To do so, just adjust the provided Dockerfile and docker-compose.yaml of this package to fit your needs based on the provided example in the file docker_app.py. To build the docker image, run the following command in the terminal:dockercomposebuildlastly, we can run the docker-compose file with the following command and start aas2openapi, AAS server and submodel server at the same time:dockercomposeupIf you want to start the middleware also with a user interface for the AAS and a mongo db backend for AAS, you can use the following command:dockercompose-fdocker-compose-ui.yamlup-dThe user interface is then available athttp://localhost:3000/. After posting some AAS with the middleware (see above), you can add the AAS to the user interface by clicking on the "+" button and entering the AAS id (base64 encoded). The AAS is then available in the user interface.Contributingaas2openapiis a new project and has therefore much room for improvement. Therefore, it would be a pleasure to get feedback or support! If you want to contribute to the package, either create issues onaas2openapis github pagefor discussing new features or contact me directly viagithuboremail.LicenseThe package is licensed under theMIT license.AcknowledgementsWe extend our sincere thanks to the German Federal Ministry for Economic Affairs and Climate Action
(BMWK) for supporting this research project 13IK001ZF “Software-Defined Manufacturing for the
automotive and supplying industryhttps://www.sdm4fzi.de/.