Over time, some general coding rules have been established and some common patterns created. If you find one in the code and it is not here, you can update the document.
Over time, some general coding rules have been established and some common patterns created. If you find one in the code and it is not here, you can update the document.
## Overview
## Overview
Here some general thoughts on coding rules:
Here are some general thoughts on coding rules:
- Follow [PEP8](https://www.python.org/dev/peps/pep-0008/), if possible. Also read [PEP20](https://www.python.org/dev/peps/pep-0020/) and follow it by idea and spirit.
- Follow [PEP8](https://www.python.org/dev/peps/pep-0008/), if possible. Also read [PEP20](https://www.python.org/dev/peps/pep-0020/) and follow it by idea and spirit.
- Use variable names that are self-explaining and consisted. Some database scheme names are currently not following this and should be renames (lot of work)
- Use variable names that are self-explaining and consisted. Some database scheme names are currently not following this and should be renamed (lot of work)
- If possible, do typing of new functions. Do typing (or correct typing) in docstrings. Hint: flask render_template returns a string (str) and flask redirect returns a response object (from werkzeug.wrappers.response import Response).
- If possible, do typing of new functions. Do typing (or correct typing) in docstrings. Hint: flask render_template returns a string (str) and flask redirect returns a response object (from werkzeug.wrappers.response import Response).
Before submit to git:
Before submit to git:
- Code should be formatted by "black" with 105 character per line.
- Code should be formatted by "black" with 105 character per line.
- Code should be checked by pylint and seen, if the complains make sense. It has problems with SQLAlchemy as it contains a lot of "Meta" stuff - we started a pylintrc to suppress some of the false positives.
- Code should be checked by pylint and seen if the complaints make sense. It has problems with SQLAlchemy as it contains a lot of "Meta" stuff - we started a pylintrc to suppress some of the false positives.
- Docstrings should be checked with pydocstyle using the "numpy" style.
- Docstrings should be checked with pydocstyle using the "numpy" style.
- Code is in parts typed and we have a working mypy.ini. Hence, run mypy and see, if there are any (new) problems.
- Code is in parts typed, and we have a working mypy.ini. Hence, run mypy and see, if there are any (new) problems.
- Run the tests with pytest.
- Run the tests with pytest.
## Variables
## Variables
We have a set of reserved variables that should be used throughout the project:
We have a set of reserved variables that should be used throughout the project:
| Variable| What for| Exception|
| Variable| What for| Exception|
| ------ | ------ |------|
| ------ | ------ |------|
| sid, s_id| ESS IDs | None |
| sid, s_id| ESS IDs | None |
| mid, m_id | PPM IDs| None|
| mid, m_id | PPM IDs| None|
| rid, r_id | Report IDs | None |
| rid, r_id | Report IDs | None |
|did, d_id | Document ids | None |
|did, d_id | Document ids | None |
| pid, pid | parent document ids | None |
| pid, pid | parent document ids | None |
| sample | ESS database record | Functions in the sample.py module|
| sample | ESS database record | Functions in the sample.py module|
| measurement | PPM database record | Functions in the measurement.py module |
| measurement | PPM database record | Functions in the measurement.py module |
| report | Report database entry | Functions in the report.py module|
| report | Report database entry | Functions in the report.py module|
| user | User database entry | some like new_user, s_user |
| user | User database entry | some like new_user, s_user |
Remember: Special cases aren't special enough to break the rules.
Remember: Special cases aren't special enough to break the rules.
Beside this, more relaxed, the use of following things is suggested:
Besides this, more relaxed, the use of following things is suggested:
| Variable| What for|
| Variable| What for|
| ------ | ------ |
| ------ | ------ |
| mtype | Measurement type database entry |
| mtype | Measurement type database entry |
| ttype | Template type |
| ttype | Template type |
| d_type | Directory type (Sample, Measurement or Report)|
| d_type | Directory type (Sample, Measurement or Report)|
## Documentation
## Documentation
All functions should have a docsstring following the [numpy style](https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard).
All functions should have a docsstring following the [numpy style](https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard).
We encourage to do typing of the variable inside the docstring. We use sphinx to automatically create a HTML documentation of the API. Needs more work and improvement. To make our life easier, we use markdown files for sphinx.
We encourage to do typing of the variable inside the docstring. We use sphinx to automatically create an HTML documentation of the API. Needs more work and improvement. To make our life easier, we use markdown files for sphinx.
We use the read_the_docs theme as it makes much nicer output.
We use the read_the_docs theme, as it makes much nicer output.
## Database access and transaction
## Database access and transaction
We use Flask-SQLALchemy for all database accesses and transaction. No direct SQL or no direct SQLAlchemy.
We use Flask-SQLALchemy for all database accesses and transaction. No direct SQL or no direct SQLAlchemy.
If we have more complex database transaction, i.e. more then one line like a query, the database_transaction module should be used. It already contains general functions for create and update of most database schemes.
If we have more complex database transaction, i.e. more than one line like a query, the database_transaction module should be used. It already contains general functions for create and update of most database schemes.
To ensure that things are really written to the database, we implemented a context manger for the database and it should be used for anything that changes the database (updates, delete and create of entries). The common pattern is
To ensure that things are really written to the database, we implemented a context manger for the database, and it should be used for anything that changes the database (updates, delete and create of entries). The common pattern is
or if you need a session it should be named db_session (to seperate from login_session) and inside the database_transaction.py module:
or if you need a session it should be named db_session (to seperate from login_session) and inside the database_transaction.py module:
~~~~
~~~~
with Transaction(database) as db_session:
with Transaction(database) as db_session:
db_session.add(doc)
db_session.add(doc)
~~~~
~~~~
The create and update functions for the database entries in database_transaction normally take as input database: `database: SQLAlchemy, db_model: db_model_class, info_dict: dict`
The create and update functions for the database entries in database_transaction normally take as input database: `database: SQLAlchemy, db_model: db_model_class, info_dict: dict`
**There should be no direct commits by db.session.commit().**
**There should be no direct commits by db.session.commit().**
Sometimes the db_model_object is created and just passed to the function. We might want to change this.
Sometimes the db_model_object is created and just passed to the function. We might want to change this.
## Working with the session cookie
## Working with the session cookie
To avoid confusion with the database session, the session cookie from flask is importat as `login_session` and should be addressed like this
To avoid confusion with the database session, the session cookie from flask is imported as `login_session` and should be addressed like this