|
1 | | -# Server-Test |
| 1 | +# Kontroll BCF API server - OpenCDE APIs |
2 | 2 |
|
3 | | -``` |
4 | | -$ pip install -r requirements.txt |
5 | | -$ cd bcfserver/ |
6 | | -$ python |
7 | | ->>> from run import db |
8 | | ->>> db.create_all() |
9 | | -$ export FLASK_APP=run.py |
10 | | -$ flask run |
11 | | -``` |
| 3 | +## What is this? |
12 | 4 |
|
13 | | -Go to [http://localhost:5000](http://localhost:5000) to see the server |
| 5 | +OpenCDE APIs: |
| 6 | +Foundation API, |
| 7 | +BCF API, |
| 8 | +Documents API |
| 9 | +implemented in python, |
| 10 | +the FastAPI framework |
| 11 | +and the Neo4j graph database. |
14 | 12 |
|
15 | | -# Register the user |
| 13 | +This is server software. To run or test this code you need to set up your server to work with a client. |
| 14 | +This server was developed and tested using Solibri as a client. To use a client with this server you need to configure |
| 15 | +a client id and a client key. |
16 | 16 |
|
17 | | -1. Go to http://localhost:5000/register to register the user |
18 | | -2. Create the client |
19 | | -3. For grant type enter authorization_code |
20 | | -4. For response_type enter code secret |
21 | | -5. Enter the scope and create the client |
| 17 | +You also need to configure encrypted communication and authentication using HTTP and OAuth2. |
| 18 | +And then you need an SSL-certificate. To get an SSL-certificate you need your own domain name. |
| 19 | +Solibri can only connect to preconfigured domains. |
22 | 20 |
|
23 | | -### You will be redirected to the page with the details of your client id and secret |
| 21 | +This means that it is not so easy to test this software. |
| 22 | +In the future I hope an open source BCF/CDE-client can be developed to access this server. |
| 23 | +Maybe Blender BIM in the future could be extended with such BCF/CDE-client functionality. |
24 | 24 |
|
25 | | -# Foundation API |
| 25 | +## Background |
26 | 26 |
|
27 | | -- Set the Base URL will be `http://127.0.0.1:5000/` |
| 27 | +You can read some background information about the project here: |
| 28 | + |
| 29 | +https://martin.wiss.se/data/bcf_ifc_graph.pdf |
| 30 | + |
| 31 | +The name of this project is Kontroll BCF API server because it was originally |
| 32 | +developed as a POC prototype to test if BCF API could be used for digital inspection plans |
| 33 | +for building permits (translated as "kontroll-plan" in Swedish language). |
| 34 | + |
| 35 | +## Code structure |
| 36 | + |
| 37 | +/docker-compose.yml |
| 38 | +You bring up the project using this file. |
| 39 | + |
| 40 | +/api/Dockerfile |
| 41 | +Contains instructions for the FastAPI container. |
| 42 | +Referenced by /docker-compose.yml |
| 43 | + |
| 44 | +/api/app |
| 45 | +Contains the server application. |
| 46 | + |
| 47 | +/api/app/main.py |
| 48 | +This is where the application starts. |
| 49 | +The FastAPI-container will run this script on uvicorn. |
| 50 | +main.py will load routes from scripts in the /api/app/api folder. |
| 51 | + |
| 52 | +/api/app/api |
| 53 | +This is where the FastAPI routes are defined. |
| 54 | + |
| 55 | +/api/app/repository |
| 56 | +Routes often runs methods that will read or write data to or from a database. |
| 57 | +This is where methods that read or write data from database are declared. |
| 58 | + |
| 59 | +/api/app/database |
| 60 | +Some general methods to interact with database. |
| 61 | + |
| 62 | +/api/app/db_config |
| 63 | +When the Neo4j container is launched it will initialize a database |
| 64 | +with some test data from init.cypher. This initial state does not represent |
| 65 | +all data. Model.cypher contains a more complete model. |
| 66 | + |
| 67 | +/api/app/ifcgraph |
| 68 | +Script to import data from IFC STEP file to Neo4j. |
| 69 | + |
| 70 | +/api/app/models |
| 71 | +Pydantic models used to define the JSON structures of requests and responses. |
| 72 | +Models are arranged in files depending on if it is request or response |
| 73 | +or both (common) or not at all (other). |
| 74 | + |
| 75 | +/api/app/security |
| 76 | +Contains methods for OAuth2 and a method to get the secrets used. |
| 77 | +You need to create your own secrets and put them in the /secrets folder. |
| 78 | +Secrets are more secure than environment values. |
| 79 | + |
| 80 | +/api/app/templets |
| 81 | +Jinja2 templates used to generate some webpages necessary for OAuth2 flow and Documents API flow. |
| 82 | + |
| 83 | +/api/app/requirements.txt |
| 84 | +Generated using pipreqs not pip freeze. |
| 85 | + |
| 86 | +## Deployment |
| 87 | + |
| 88 | +To get this code running properly you need: |
| 89 | + |
| 90 | +- your own linux server, on premise or in the cloud |
| 91 | +- a domain name and a TLS-certificate for your domain name |
| 92 | +- a proxy server, nginx was used |
| 93 | +- to set up your proxy server to use HTTPS |
| 94 | +- to use proxy as bridge between docker network and remote |
| 95 | +- proxy (outside container) and uvicorn (inside container) should access same TLS certificate |
| 96 | +- to edit your .env file with values specific for your server and API |
| 97 | +- to replace hard coded values in code with specific values for your server and API |
| 98 | +- to create three secrets and put them in the /secrets folder |
| 99 | +- to put apoc-5.7.0-core and apoc-5.7.0-extended jars in /neo4j/plugins folder |
| 100 | +- to put an ifcopenshell.zip in /api/app/ifcopenshell folder |
| 101 | +- Docker and Neo4j software |
| 102 | +- a favicon at /favicon.ico |
| 103 | +- to run "bash restart.sh" to start and restart containers |
| 104 | +- a BCF client, registered with client ID and secret |
| 105 | + |
| 106 | +This code was developed and tested using Solibri Office as BCF client, however: |
| 107 | +Solibri Office can only connect to pre-registered servers. This means that you cannot |
| 108 | +connect to your server using a regular version of Solibri Office. If you want to use Solibri, |
| 109 | +then you will have to first kindly ask Solibri if they want to add your server |
| 110 | +to the list of registered servers. An alternative is to develop your own BCF client |
| 111 | +or to use this existing BCF API client module for python to build your own client script: |
| 112 | + |
| 113 | +https://pypi.org/project/bcf-client/ |
| 114 | + |
| 115 | +I do not know of any working BCF API client plugins for Revit or Archicad that allows |
| 116 | +connecting to arbitrary BCF API servers. It seems like most plugins instead were developed to |
| 117 | +only connect to a specific BCF API server. I think that is contradictory because BCF is an open standard |
| 118 | +intended to facilitate communication between multiple clients and servers. |
| 119 | +A BCF API client that can connect to multiple arbitrary BCF API servers would be a good thing to develop. |
| 120 | + |
| 121 | +## TODO |
| 122 | + |
| 123 | +The original intention of the code was just to create a prototype for private testing. |
| 124 | +Improvements are needed to collaborate on this code or to deploy this system in production. |
| 125 | + |
| 126 | +Suggested improvements: |
| 127 | + |
| 128 | +- General code structure refactoring |
| 129 | +- Better commenting |
| 130 | +- Testing scripts, unit testing |
| 131 | +- Better error handling |
| 132 | +- More consistent logging |
| 133 | +- Easier deployment |
| 134 | +- User registration and admin system |
| 135 | +- BCF client registration functionality |
| 136 | +- OData to Cypher converter |
| 137 | +- Documents API and BCF API integration |
| 138 | +- More complete OpenAPI documentation of routes |
| 139 | +- More complete documentation of pydantic models |
| 140 | +- Improvements on IFC-graph |
| 141 | +- BCF event logging |
| 142 | +- Implement also the routes that Solibri Office does not support |
| 143 | +- Replace hard coded values with .env values |
| 144 | +- Improve security before any kind of deployment in production |
| 145 | +- Making full use of native IFC (for example allowing BCF API to edit IFC directly using BIM snippets) |
| 146 | +- Integrate BCF API BIM snippets editing with GIT commits |
| 147 | + |
| 148 | +## Prototype |
| 149 | + |
| 150 | +This code was developed and tested on a system using: |
| 151 | + |
| 152 | +- Ubuntu 20 |
| 153 | +- Nginx 1.18 |
| 154 | +- Lets encrypt, certbot |
| 155 | +- Docker 20 |
| 156 | + |
| 157 | +## Suggested reading |
| 158 | + |
| 159 | +### API |
| 160 | + |
| 161 | +- FastAPI documentation |
| 162 | + https://fastapi.tiangolo.com/ |
| 163 | + |
| 164 | +- Building Python Microservices with FastAPI |
| 165 | + https://www.packtpub.com/product/building-python-microservices-with-fastapi/9781803245966 |
| 166 | + |
| 167 | +- Building Python Web APIs with FastAPI |
| 168 | + https://www.packtpub.com/product/building-python-web-apis-with-fastapi/9781801076630 |
| 169 | + |
| 170 | +- Building Data Science Applications with FastAPI - Second Edition |
| 171 | + https://www.packtpub.com/product/building-data-science-applications-with-fastapi-second-edition/9781837632749 |
| 172 | + |
| 173 | +- Pydantic docs |
| 174 | +https://docs.pydantic.dev/latest/ |
| 175 | + |
| 176 | +- OData v4 |
| 177 | +https://www.odata.org/documentation/ |
| 178 | + |
| 179 | +### OAuth2 |
| 180 | + |
| 181 | +- Mastering OAuth 2.0 |
| 182 | +https://www.packtpub.com/product/mastering-oauth-20/9781784395407 |
| 183 | + |
| 184 | +- OAuth 2.0 Cookbook |
| 185 | +https://www.packtpub.com/product/oauth-20-cookbook/9781788295963 |
| 186 | + |
| 187 | +- OAuth2 with Password (and hashing), Bearer with JWT tokens |
| 188 | +https://fastapi.tiangolo.com/ur/tutorial/security/oauth2-jwt/ |
| 189 | + |
| 190 | +- Authorization Code Flow |
| 191 | +https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow |
| 192 | + |
| 193 | +- What is the OAuth 2.0 Authorization Code Grant Type? |
| 194 | +https://developer.okta.com/blog/2018/04/10/oauth-authorization-code-grant-type |
| 195 | + |
| 196 | +### Neo4j and Cypher |
| 197 | + |
| 198 | +- Neo4j Cypher Manual |
| 199 | +https://neo4j.com/docs/cypher-manual/current/introduction/ |
| 200 | + |
| 201 | +- Using Neo4j from python |
| 202 | +https://neo4j.com/docs/getting-started/languages-guides/neo4j-python/ |
| 203 | + |
| 204 | +- Building Neo4j Applications with Python |
| 205 | +https://graphacademy.neo4j.com/courses/app-python/ |
| 206 | + |
| 207 | +- The Property Graph Model |
| 208 | +https://neo4j.com/developer/graph-database/#property-graph |
| 209 | + |
| 210 | +### OpenCDE APIs |
| 211 | + |
| 212 | +- BCF API |
| 213 | +https://github.com/buildingSMART/BCF-API |
| 214 | + |
| 215 | +- Documents API |
| 216 | +https://github.com/buildingSMART/documents-API |
| 217 | + |
| 218 | +- Foundation API |
| 219 | +https://github.com/buildingSMART/foundation-API |
| 220 | + |
| 221 | +- Open CDE APIs OAuth2 Example |
| 222 | +https://github.com/buildingSMART/foundation-API/blob/v1.0/OAuth2Examples.md |
| 223 | + |
| 224 | +### Server |
| 225 | + |
| 226 | +- Docker documentation |
| 227 | +https://docs.docker.com/ |
| 228 | + |
| 229 | +- Docker Compose overview |
| 230 | +https://docs.docker.com/compose/ |
| 231 | + |
| 232 | +- How to use secrets in Docker Compose |
| 233 | +https://docs.docker.com/compose/use-secrets/ |
| 234 | + |
| 235 | +- NGINX Reverse Proxy documentation |
| 236 | +https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/ |
| 237 | + |
| 238 | +- Certbot documentation |
| 239 | +https://eff-certbot.readthedocs.io/en/stable/ |
| 240 | + |
| 241 | +### IFC |
| 242 | + |
| 243 | +- Native IFC |
| 244 | +https://github.com/brunopostle/ifcmerge/blob/main/docs/whitepaper.rst |
| 245 | + |
| 246 | +- IFC Specifications Database |
| 247 | +https://technical.buildingsmart.org/standards/ifc/ifc-schema-specifications/ |
| 248 | + |
| 249 | +- IFC-graph for facilitating building information access and query |
| 250 | +https://www.sciencedirect.com/science/article/pii/S0926580523000389 |
| 251 | + |
| 252 | +- IFCOpenShell documentation |
| 253 | +https://blenderbim.org/docs-python/ |
| 254 | + |
| 255 | +### Frontend |
| 256 | + |
| 257 | +- Jinja2 Documentation |
| 258 | +https://svn.python.org/projects/external/Jinja-2.1.1/docs/_build/html/index.html |
| 259 | + |
| 260 | +- Bootstrap |
| 261 | +https://getbootstrap.com/docs/4.1/getting-started/introduction/ |
| 262 | + |
| 263 | +- jQuery |
| 264 | +https://api.jquery.com/ |
| 265 | + |
| 266 | +## License |
| 267 | + |
| 268 | +The GNU Affero General Public License is a free, |
| 269 | +copyleft license for software and other kinds of works, |
| 270 | +specifically designed to ensure cooperation with the community |
| 271 | +in the case of network server software. |
| 272 | + |
| 273 | +https://www.gnu.org/licenses/agpl-3.0.en.html |
| 274 | + |
| 275 | +See the /LICENSE file. |
0 commit comments