openmodule 13.1.4__tar.gz → 13.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openmodule-13.1.4 → openmodule-13.3.0}/ChangeLog +13 -26
- openmodule-13.3.0/PKG-INFO +133 -0
- openmodule-13.3.0/README.md +110 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/access_service.md +2 -0
- openmodule-13.3.0/docs/anonymization.md +52 -0
- openmodule-13.3.0/docs/cleanup.md +42 -0
- openmodule-13.3.0/docs/coding_standard.md +79 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/commands.md +6 -3
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/connection_status_listener.md +3 -1
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/csv_export.md +8 -1
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/database.md +23 -11
- openmodule-13.3.0/docs/deprecated.md +56 -0
- openmodule-13.3.0/docs/event_sending.md +73 -0
- openmodule-13.3.0/docs/getting_started.md +321 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/health.md +60 -3
- openmodule-13.3.0/docs/images/broker.drawio.png +0 -0
- openmodule-13.3.0/docs/package_reader.md +65 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/rpc.md +28 -8
- openmodule-13.3.0/docs/settings.md +60 -0
- openmodule-13.1.4/docs/settings.md → openmodule-13.3.0/docs/settings_provider.md +2 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/testing.md +100 -9
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/translation.md +2 -0
- openmodule-13.3.0/docs/utils.md +66 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/database/database.py +18 -20
- openmodule-13.3.0/openmodule/utils/cleanup.py +40 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/eventlog.py +5 -2
- openmodule-13.3.0/openmodule.egg-info/PKG-INFO +133 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule.egg-info/SOURCES.txt +11 -2
- openmodule-13.3.0/openmodule.egg-info/pbr.json +1 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/connection_status.py +3 -0
- openmodule-13.3.0/openmodule_test/database.py +137 -0
- openmodule-13.3.0/tests/migration_test_database/alembic_migration_test_database.sqlite3 +0 -0
- openmodule-13.3.0/tests/test_alembic_migrations.py +173 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_database.py +91 -3
- openmodule-13.3.0/tests/test_utils_cleanup.py +107 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_utils_eventlog.py +5 -3
- openmodule-13.1.4/PKG-INFO +0 -443
- openmodule-13.1.4/README.md +0 -420
- openmodule-13.1.4/docs/coding_standard.md +0 -27
- openmodule-13.1.4/docs/core.md +0 -28
- openmodule-13.1.4/docs/event_sending.md +0 -8
- openmodule-13.1.4/docs/package_reader.md +0 -20
- openmodule-13.1.4/docs/qc.md +0 -3
- openmodule-13.1.4/openmodule.egg-info/PKG-INFO +0 -443
- openmodule-13.1.4/openmodule.egg-info/pbr.json +0 -1
- openmodule-13.1.4/openmodule_test/database.py +0 -71
- {openmodule-13.1.4 → openmodule-13.3.0}/.gitlab-ci.yml +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/AUTHORS +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/LICENSE +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/deprecated_code/README.md +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/deprecated_code/access_service/openmodule/models/access_service.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/deprecated_code/access_service/openmodule/utils/access_service.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/deprecated_code/access_service/openmodule_test/access_service.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/deprecated_code/access_service/tests/test_utils_access_service.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/deprecated_code/api/openmodule/utils/api.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/deprecated_code/api/openmodule_test/api.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/deprecated_code/api/tests/test_utils_api.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/deprecated_code/package_reader/openmodule/utils/package_reader.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/deprecated_code/package_reader/openmodule_test/fake_package_creator.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/deprecated_code/package_reader/tests/test_package_reader.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/known_issues.md +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/docs/migrations.md +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/__init__.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/alert.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/checks.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/config.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/connection_status.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/core.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/database/custom_types.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/database/env.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/dispatcher.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/health.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/logging.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/messaging.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/models/__init__.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/models/access_service.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/models/alert.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/models/base.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/models/io.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/models/kv_store.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/models/presence.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/models/privacy.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/models/rpc.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/models/settings.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/models/validation.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/models/vehicle.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/rpc/__init__.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/rpc/client.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/rpc/common.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/rpc/server.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/sentry.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/threading.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/__init__.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/access_service.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/charset.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/csv_export.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/databox.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/db_helper.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/io.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/kv_store.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/matching.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/misc_functions.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/package_reader.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/presence.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/schema.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/settings.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/translation.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule/utils/validation.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule.egg-info/dependency_links.txt +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule.egg-info/not-zip-safe +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule.egg-info/requires.txt +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule.egg-info/top_level.txt +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_commands/__init__.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_commands/setup.cfg +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_commands/setup.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_commands/translate.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/__init__.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/alert.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/core.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/eventlistener.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/files.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/gate.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/health.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/interrupt.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/io_simulator.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/package_reader.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/presence.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/requirements.txt +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/rpc.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/settings.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/setup.cfg +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/setup.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/utils.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/openmodule_test/zeromq.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/requirements.txt +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/setup.cfg +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/setup.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/test-requirements.txt +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/__init__.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/config.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/database_models_migration.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/database_models_test.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/invalid_database/alembic/README +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/invalid_database/alembic/__init__.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/invalid_database/alembic/env.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/invalid_database/alembic/script.py.mako +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/invalid_database/alembic/versions/ff26e54332f9_datetime_models.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/invalid_database/alembic.ini +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/invalid_database/makemigration.sh +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/migration_test_database/__init__.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/migration_test_database/alembic/__init__.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/migration_test_database/alembic/env.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/migration_test_database/alembic/script.py.mako +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/migration_test_database/alembic/versions/19789aa5361c_initial.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/migration_test_database/alembic/versions/19d887929ae7_alter.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/migration_test_database/alembic/versions/__init__.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/migration_test_database/alembic.ini +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/migration_test_database/makemigration.sh +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/configs/config.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/configs/test_config.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/configs/test_config_1.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/standard_schemes/DEFAULT-10.yml +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/standard_schemes/DEFAULT-20.yml +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/standard_schemes/LEGACY-0.yml +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/translation/locale/de/LC_MESSAGES/translation.mo +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/translation/locale/de/LC_MESSAGES/translation.po +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/translation/locale/en/LC_MESSAGES/translation.mo +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/translation/locale/en/LC_MESSAGES/translation.po +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/translation/locale/translation.pot +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/translation/translate.sh +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/utils_matching/A-10.yml +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/utils_matching/A-20.yml +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/utils_matching/DEFAULT-10.yml +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/utils_matching/DEFAULT-20.yml +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/utils_matching/DEFAULT-30.yml +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/utils_matching/LEGACY-0.yml +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/utils_matching/TEST-10.yml +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/utils_matching/TEST-20.yml +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/utils_matching/TEST-30.yml +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/resources/utils_matching/TEST-40.yml +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_access_service_database/alembic/__init__.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_access_service_database/alembic/env.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_access_service_database/alembic/script.py.mako +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_access_service_database/alembic/versions/7bd4fcd38fde_removed_nfc_and_pin.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_access_service_database/alembic/versions/9ca98a2e5674_added_parksettings_id.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_access_service_database/alembic/versions/c821971f9230_initial.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_access_service_database/alembic.ini +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_access_service_database/makemigration.sh +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_alert.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_checks.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_config.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_connection_status.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_core.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_database/alembic/__init__.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_database/alembic/env.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_database/alembic/script.py.mako +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_database/alembic/versions/32b8c728abbf_initial.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_database/alembic.ini +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_database/makemigration.sh +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_dispatcher.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_health.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_interrupt.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_io_listen.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_kv_store_database/alembic/__init__.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_kv_store_database/alembic/env.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_kv_store_database/alembic/script.py.mako +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_kv_store_database/alembic/versions/9c5c944221f4_deprecated_kv_entry_example.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_kv_store_database/alembic/versions/c55a69026a25_initial.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_kv_store_database/alembic.ini +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_kv_store_database/makemigration.sh +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_kv_store_multiple_database/alembic/README +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_kv_store_multiple_database/alembic/__init__.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_kv_store_multiple_database/alembic/env.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_kv_store_multiple_database/alembic/script.py.mako +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_kv_store_multiple_database/alembic/versions/cdb3214131a9_initial.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_kv_store_multiple_database/alembic.ini +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_kv_store_multiple_database/makemigration.sh +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_messaging.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_mockrpcclient.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_model.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_rpc.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_schema.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_sentry.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_test_alert.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_test_gate.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_test_zeromq.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_utils_access_service.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_utils_charset.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_utils_csv_export.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_utils_databox.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_utils_kv_store.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_utils_kv_store_multiple.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_utils_matching.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_utils_misc_functions.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_utils_package_reader.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_utils_presence.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_utils_settings.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_utils_validation.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tests/test_utils_vehicle.py +0 -0
- {openmodule-13.1.4 → openmodule-13.3.0}/tox.ini +0 -0
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
CHANGES
|
|
2
2
|
=======
|
|
3
3
|
|
|
4
|
+
v13.3.0
|
|
5
|
+
-------
|
|
6
|
+
|
|
7
|
+
* [OM-359] cleanup helper function
|
|
8
|
+
|
|
9
|
+
v13.2.0
|
|
10
|
+
-------
|
|
11
|
+
|
|
12
|
+
* OM 187 Alembic migration test mixin
|
|
13
|
+
* add a testcase for expiring session data while adding new models (noticed in OM-327)
|
|
14
|
+
* Aktualisierung der Dokumentation
|
|
15
|
+
* OM-255
|
|
16
|
+
|
|
4
17
|
v13.1.4
|
|
5
18
|
-------
|
|
6
19
|
|
|
@@ -145,27 +158,6 @@ v11.1.0.rc4
|
|
|
145
158
|
|
|
146
159
|
* arivo-schedule in public pip
|
|
147
160
|
* use temporary arivo-schedule package
|
|
148
|
-
|
|
149
|
-
v11.1.0.rc3
|
|
150
|
-
-----------
|
|
151
|
-
|
|
152
|
-
* changed docs and requirements for schedule library until its a pip package
|
|
153
|
-
|
|
154
|
-
v11.1.0.rc2
|
|
155
|
-
-----------
|
|
156
|
-
|
|
157
|
-
* added fork of schedule package
|
|
158
|
-
|
|
159
|
-
v11.1.0.rc1
|
|
160
|
-
-----------
|
|
161
|
-
|
|
162
|
-
* databox upload now can have dst as folder (endswith "/")
|
|
163
|
-
|
|
164
|
-
v11.1.0.rc0
|
|
165
|
-
-----------
|
|
166
|
-
|
|
167
|
-
* fixed testcase
|
|
168
|
-
* small changes in csv export and databox upload adding more testcases docs
|
|
169
161
|
* removed mock rpcs from schema
|
|
170
162
|
|
|
171
163
|
v11.0.3
|
|
@@ -226,8 +218,3 @@ v10.0.1
|
|
|
226
218
|
v10.0.0
|
|
227
219
|
-------
|
|
228
220
|
|
|
229
|
-
* v10
|
|
230
|
-
* README Update for creation of dist structure [skip ci]
|
|
231
|
-
* don't schedule any more rpc's if we are already shutdown
|
|
232
|
-
* Update README.md
|
|
233
|
-
* Update README.md
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: openmodule
|
|
3
|
+
Version: 13.3.0
|
|
4
|
+
Summary: Libraries for developing the arivo openmodule
|
|
5
|
+
Home-page: https://gitlab.com/arivo-public/device-python/openmodule.git
|
|
6
|
+
Author: ARIVO
|
|
7
|
+
Author-email: support@arivo.co
|
|
8
|
+
License: GNU General Public License v2 (GPLv2)
|
|
9
|
+
Keywords: arivo openmodule
|
|
10
|
+
Platform: UNKNOWN
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: GNU General Public License v2 (GPLv2)
|
|
13
|
+
Classifier: Programming Language :: Python
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Description-Content-Type: text/markdown; charset=UTF-8
|
|
17
|
+
Provides-Extra: test
|
|
18
|
+
Provides-Extra: commands
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
|
|
21
|
+
# OpenModule V2
|
|
22
|
+
|
|
23
|
+
[TOC]
|
|
24
|
+
|
|
25
|
+
## Quickstart
|
|
26
|
+
|
|
27
|
+
You can install this library via pip:
|
|
28
|
+
```bash
|
|
29
|
+
pip install openmodule
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
#### Development with Feature Branches
|
|
33
|
+
|
|
34
|
+
During development it might be necessary to install a version of openmodule, where no pip package exists.
|
|
35
|
+
Below you can find how to install a certain openmodule branch for your application with pip.
|
|
36
|
+
|
|
37
|
+
##### Openmodule
|
|
38
|
+
|
|
39
|
+
Bash command:
|
|
40
|
+
```bash
|
|
41
|
+
pip install "git+https://gitlab.com/arivo-public/device-python/openmodule@<branch>#egg=openmodule"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
requirements.txt:
|
|
45
|
+
```text
|
|
46
|
+
git+https://gitlab.com/arivo-public/device-python/openmodule@<branch>#egg=openmodule
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
##### Openmodule Test
|
|
50
|
+
|
|
51
|
+
Bash command:
|
|
52
|
+
```bash
|
|
53
|
+
pip install "git+https://gitlab.com/arivo-public/device-python/openmodule@<branch>#egg=openmodule-test&subdirectory=openmodule_test"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
requirements.txt:
|
|
57
|
+
```text
|
|
58
|
+
git+https://gitlab.com/arivo-public/device-python/openmodule@<branch>#egg=openmodule-test&subdirectory=openmodule_test
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
##### Openmodule Commands
|
|
62
|
+
|
|
63
|
+
Bash command:
|
|
64
|
+
```bash
|
|
65
|
+
pip install "git+https://gitlab.com/arivo-public/device-python/openmodule@<branch>#egg=openmodule-commands&subdirectory=openmodule_commands
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
requirements.txt:
|
|
69
|
+
```text
|
|
70
|
+
git+https://gitlab.com/arivo-public/device-python/openmodule@<branch>#egg=openmodule-commands&subdirectory=openmodule_commands
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### Local Development
|
|
74
|
+
|
|
75
|
+
Sometimes you want to test local changes of the Openmodule library in device services and therefore you can do a local
|
|
76
|
+
installation of the library. We use the
|
|
77
|
+
[editable installs](https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs) of Pip for this.
|
|
78
|
+
|
|
79
|
+
##### Openmodule
|
|
80
|
+
|
|
81
|
+
bash command:
|
|
82
|
+
```bash
|
|
83
|
+
pip install -e <path_to_openmodule_root>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
##### Openmodule Test
|
|
87
|
+
|
|
88
|
+
bash command:
|
|
89
|
+
```bash
|
|
90
|
+
pip install -e <path_to_openmodule_root>/openmodule_test/
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
##### Openmodule Commands
|
|
94
|
+
|
|
95
|
+
bash command:
|
|
96
|
+
```bash
|
|
97
|
+
pip install -e <path_to_openmodule_root>/openmodule_commands/
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Changes
|
|
101
|
+
|
|
102
|
+
- [Breaking Changes](docs/migrations.md)
|
|
103
|
+
- [Known Issues](docs/known_issues.md)
|
|
104
|
+
|
|
105
|
+
## Documentation
|
|
106
|
+
|
|
107
|
+
### Openmodule
|
|
108
|
+
|
|
109
|
+
- [Getting Started](docs/getting_started.md)
|
|
110
|
+
- [Coding Standard](docs/coding_standard.md)
|
|
111
|
+
- [Settings](docs/settings.md)
|
|
112
|
+
- [RPC](docs/rpc.md)
|
|
113
|
+
- [Health](docs/health.md)
|
|
114
|
+
- [Database](docs/database.md)
|
|
115
|
+
- [Eventlog](docs/event_sending.md)
|
|
116
|
+
- [Package Reader](docs/package_reader.md)
|
|
117
|
+
- [Anonymization](docs/anonymization.md)
|
|
118
|
+
- [Connection Status Listener](docs/connection_status_listener.md)
|
|
119
|
+
- [Settings Provider](docs/settings_provider.md)
|
|
120
|
+
- [Access Service](docs/access_service.md)
|
|
121
|
+
- [CSV Export](docs/csv_export.md)
|
|
122
|
+
- [Translations](docs/translation.md)
|
|
123
|
+
- [Utils](docs/utils.md)
|
|
124
|
+
- [Deprecated Features](docs/deprecated.md)
|
|
125
|
+
- [Testing](docs/testing.md)
|
|
126
|
+
- [File Cleanup](docs/cleanup.md)
|
|
127
|
+
|
|
128
|
+
### Openmodule Commands
|
|
129
|
+
|
|
130
|
+
- [Openmodule Commands](docs/commands.md)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# OpenModule V2
|
|
2
|
+
|
|
3
|
+
[TOC]
|
|
4
|
+
|
|
5
|
+
## Quickstart
|
|
6
|
+
|
|
7
|
+
You can install this library via pip:
|
|
8
|
+
```bash
|
|
9
|
+
pip install openmodule
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
#### Development with Feature Branches
|
|
13
|
+
|
|
14
|
+
During development it might be necessary to install a version of openmodule, where no pip package exists.
|
|
15
|
+
Below you can find how to install a certain openmodule branch for your application with pip.
|
|
16
|
+
|
|
17
|
+
##### Openmodule
|
|
18
|
+
|
|
19
|
+
Bash command:
|
|
20
|
+
```bash
|
|
21
|
+
pip install "git+https://gitlab.com/arivo-public/device-python/openmodule@<branch>#egg=openmodule"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
requirements.txt:
|
|
25
|
+
```text
|
|
26
|
+
git+https://gitlab.com/arivo-public/device-python/openmodule@<branch>#egg=openmodule
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
##### Openmodule Test
|
|
30
|
+
|
|
31
|
+
Bash command:
|
|
32
|
+
```bash
|
|
33
|
+
pip install "git+https://gitlab.com/arivo-public/device-python/openmodule@<branch>#egg=openmodule-test&subdirectory=openmodule_test"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
requirements.txt:
|
|
37
|
+
```text
|
|
38
|
+
git+https://gitlab.com/arivo-public/device-python/openmodule@<branch>#egg=openmodule-test&subdirectory=openmodule_test
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
##### Openmodule Commands
|
|
42
|
+
|
|
43
|
+
Bash command:
|
|
44
|
+
```bash
|
|
45
|
+
pip install "git+https://gitlab.com/arivo-public/device-python/openmodule@<branch>#egg=openmodule-commands&subdirectory=openmodule_commands
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
requirements.txt:
|
|
49
|
+
```text
|
|
50
|
+
git+https://gitlab.com/arivo-public/device-python/openmodule@<branch>#egg=openmodule-commands&subdirectory=openmodule_commands
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
#### Local Development
|
|
54
|
+
|
|
55
|
+
Sometimes you want to test local changes of the Openmodule library in device services and therefore you can do a local
|
|
56
|
+
installation of the library. We use the
|
|
57
|
+
[editable installs](https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs) of Pip for this.
|
|
58
|
+
|
|
59
|
+
##### Openmodule
|
|
60
|
+
|
|
61
|
+
bash command:
|
|
62
|
+
```bash
|
|
63
|
+
pip install -e <path_to_openmodule_root>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
##### Openmodule Test
|
|
67
|
+
|
|
68
|
+
bash command:
|
|
69
|
+
```bash
|
|
70
|
+
pip install -e <path_to_openmodule_root>/openmodule_test/
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
##### Openmodule Commands
|
|
74
|
+
|
|
75
|
+
bash command:
|
|
76
|
+
```bash
|
|
77
|
+
pip install -e <path_to_openmodule_root>/openmodule_commands/
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Changes
|
|
81
|
+
|
|
82
|
+
- [Breaking Changes](docs/migrations.md)
|
|
83
|
+
- [Known Issues](docs/known_issues.md)
|
|
84
|
+
|
|
85
|
+
## Documentation
|
|
86
|
+
|
|
87
|
+
### Openmodule
|
|
88
|
+
|
|
89
|
+
- [Getting Started](docs/getting_started.md)
|
|
90
|
+
- [Coding Standard](docs/coding_standard.md)
|
|
91
|
+
- [Settings](docs/settings.md)
|
|
92
|
+
- [RPC](docs/rpc.md)
|
|
93
|
+
- [Health](docs/health.md)
|
|
94
|
+
- [Database](docs/database.md)
|
|
95
|
+
- [Eventlog](docs/event_sending.md)
|
|
96
|
+
- [Package Reader](docs/package_reader.md)
|
|
97
|
+
- [Anonymization](docs/anonymization.md)
|
|
98
|
+
- [Connection Status Listener](docs/connection_status_listener.md)
|
|
99
|
+
- [Settings Provider](docs/settings_provider.md)
|
|
100
|
+
- [Access Service](docs/access_service.md)
|
|
101
|
+
- [CSV Export](docs/csv_export.md)
|
|
102
|
+
- [Translations](docs/translation.md)
|
|
103
|
+
- [Utils](docs/utils.md)
|
|
104
|
+
- [Deprecated Features](docs/deprecated.md)
|
|
105
|
+
- [Testing](docs/testing.md)
|
|
106
|
+
- [File Cleanup](docs/cleanup.md)
|
|
107
|
+
|
|
108
|
+
### Openmodule Commands
|
|
109
|
+
|
|
110
|
+
- [Openmodule Commands](docs/commands.md)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
### Anonymization
|
|
2
|
+
|
|
3
|
+
[TOC]
|
|
4
|
+
|
|
5
|
+
The openmodule framework uses rpc requests and messages to trigger the anonymization of data.
|
|
6
|
+
|
|
7
|
+
* **Message:** ONLY the DSGVO device service can send a AnonymizeMessage (topic: `privacy`).
|
|
8
|
+
The message includes a session_id and vehicle_ids to delete.
|
|
9
|
+
* **RPC Request:** You can send an AnonymizeRequest with channel=`privacy`, type=`anonymize` to the DSGVO container.
|
|
10
|
+
This request only includes session_ids.
|
|
11
|
+
The DSGVO container will then match vehicle_ids to the session_ids and redistribute the request with the prior
|
|
12
|
+
mentioned message.
|
|
13
|
+
|
|
14
|
+
A container with sensitive data then needs to implement the message listener for the privacy messages (see example).
|
|
15
|
+
|
|
16
|
+
##### Example 1
|
|
17
|
+
|
|
18
|
+
The controller checked that a parking session was finished and fully paid. After a specified time, the DSGVO relevant
|
|
19
|
+
data has to be anonymized. The controller then triggers the anonymization.
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
request = AnonymizeRequest(session_ids=[session_id])
|
|
23
|
+
result = core.rpc_client.rpc("privacy", "anonymize", request)
|
|
24
|
+
if result.response.status == "ok":
|
|
25
|
+
self.log.info(f"Anonymized session {session_id}")
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
##### Example 2
|
|
29
|
+
|
|
30
|
+
The controller checked that a parking session was finished and fully paid. After a specified time, the DSGVO relevant
|
|
31
|
+
data has to be anonymized. The controller then triggers the anonymization.
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
msg = AnonymizeMessage(vehicle_ids=[vid1, vid2])
|
|
35
|
+
self.core.publish(msg, "privacy")
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The DSGVO container receives the request, matches session_ids with vehicle_ids and publishes the anonymization message.
|
|
39
|
+
It also listens on said messages and deletes vehicle images based on the vehicle_ids in the message.
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
core.messages.register("privacy", AnonymizeMessage, anonymize_data)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def anonymize_data(message: AnonymizeMessage):
|
|
46
|
+
for vid in message.vehicle_ids:
|
|
47
|
+
delete_vehicle_image_by_vehicle_id(vid)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**IMPORTANT** You still have to take care of data retention in each service separately, meaning you have to delete data
|
|
51
|
+
independently of these anonymization messages.
|
|
52
|
+
i.e. the DSGVO service deletes data if we need disk space or the eventlog deletes events after 30 days by default
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# File cleanup
|
|
2
|
+
|
|
3
|
+
With the exception for some globally defined file_patterns (e.g. debug images, log rotation files) every service is responsible for the cleanup of its files.
|
|
4
|
+
The helper function `schedule_file_cleanup` schedules a file cleanup at 2:xx local time, where xx is service name dependent to avoid that all services delete at the same time.
|
|
5
|
+
Important notes:
|
|
6
|
+
* only files will be deleted, directories are kept
|
|
7
|
+
* files are only deleted once per day
|
|
8
|
+
* files are deleted based on modified timestamp
|
|
9
|
+
* a scheduler must be used which does `.run_pending()` regularly
|
|
10
|
+
* as glob is only inclusive, an exclude regex can be specified for special cases
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
import time
|
|
17
|
+
import re
|
|
18
|
+
import schedule
|
|
19
|
+
from datetime import timedelta
|
|
20
|
+
from openmodule.utils.cleanup import schedule_file_cleanup
|
|
21
|
+
|
|
22
|
+
scheduler = schedule.Scheduler()
|
|
23
|
+
|
|
24
|
+
# delete specific file after 30 days
|
|
25
|
+
schedule_file_cleanup(scheduler, "/data/file_to_keep_30_days.txt", timedelta(days=30))
|
|
26
|
+
|
|
27
|
+
# delete png files in folder after 1 day
|
|
28
|
+
schedule_file_cleanup(scheduler, "/data/images/*.png", timedelta(days=1))
|
|
29
|
+
|
|
30
|
+
# delete jpg files in subfolders after 30 days
|
|
31
|
+
schedule_file_cleanup(scheduler, "/data/*/*.jpg", timedelta(days=30))
|
|
32
|
+
|
|
33
|
+
# delete jpg files in subfolders recursively after 30 days (e.g. /data/a.jpg, /data/d1/a.jpg, /data/d1/d2/a.jpg)
|
|
34
|
+
schedule_file_cleanup(scheduler, "/data/**/*.jpg", timedelta(days=30))
|
|
35
|
+
|
|
36
|
+
# delete jpg files in subfolders, except if regex matches, recursively after 30 days (e.g. /data/d1/a.jpg, but not /data/vehicle_images/a.jpg)
|
|
37
|
+
schedule_file_cleanup(scheduler, "/data/**/*.jpg", timedelta(days=30), re.compile('.*/vehicle_images/.*'))
|
|
38
|
+
|
|
39
|
+
while True:
|
|
40
|
+
scheduler.run_pending()
|
|
41
|
+
time.sleep(1.0)
|
|
42
|
+
```
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Openmodule Coding Standard
|
|
2
|
+
|
|
3
|
+
[TOC]
|
|
4
|
+
|
|
5
|
+
## Models
|
|
6
|
+
|
|
7
|
+
* All Messages or RPC requests MUST be defined as pydantic models in either `openmodule/models` or in `src/models` to
|
|
8
|
+
avoid confusion about datatypes.
|
|
9
|
+
|
|
10
|
+
* All Models MUST be must inherit `OpenModuleModel` or one of its children
|
|
11
|
+
|
|
12
|
+
* ZMQ Messages MUST inherit `ZMQMessage`
|
|
13
|
+
|
|
14
|
+
### Enum
|
|
15
|
+
|
|
16
|
+
As a coding standard we are using camel case and the name of the enum and value should always be the same.
|
|
17
|
+
This means you are not allowed to use a dash (`-`) in the enum value.
|
|
18
|
+
|
|
19
|
+
We are also using the `str` type for all enums, because we want to compare the enum value against strings.
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from enum import Enum
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class MyStatus(str, Enum):
|
|
26
|
+
very_good = "very_good"
|
|
27
|
+
good = "good"
|
|
28
|
+
this_is_fine = "this_is_fine"
|
|
29
|
+
something_is_wrong = "something_is_wrong"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Database
|
|
33
|
+
|
|
34
|
+
* All database models must be defined within either `openmodule/models` or in the directory `src/database`
|
|
35
|
+
|
|
36
|
+
* All database model names have to end with Model, i.e. TestModel(Base)
|
|
37
|
+
|
|
38
|
+
* All database interactions MUST be defined in functions under `src/database/database.py`. There are no other access of
|
|
39
|
+
the database in any other file.
|
|
40
|
+
|
|
41
|
+
* All functions in `src/database/database.py` MUST have the database/session as first parameter: `def stuff(db, ...)`
|
|
42
|
+
|
|
43
|
+
* All table names MUST use "_" as separator
|
|
44
|
+
|
|
45
|
+
* For single object queries only use `query.one()` and `query.first()`
|
|
46
|
+
|
|
47
|
+
## Typing
|
|
48
|
+
|
|
49
|
+
We use type annotation for functions and variables.
|
|
50
|
+
This not only improves read ability of the source code, but the IDEs and linters can
|
|
51
|
+
also use this information to provide better code completion and error checking.
|
|
52
|
+
|
|
53
|
+
### Examples
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
class MyPriceModel(OpenModuleModel):
|
|
57
|
+
price: float # net price
|
|
58
|
+
currency: str # currency
|
|
59
|
+
vat: float = 0 # amount of vat for country
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
vat_country_in_percent: float = 20.0
|
|
63
|
+
my_products: Dict[str, MyPriceModel] = {"apple": MyPriceModel(price=1.0, currency="EUR")}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def calculate_vat(price: MyPriceModel) -> float:
|
|
67
|
+
"""Calculate the vat for a product."""
|
|
68
|
+
return price.price * vat_country_in_percent / 100.0
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
We allow that function that are not returning anything to not have a return type annotation.
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
def updating_vat(products: Dict[str, MyPriceModel]):
|
|
76
|
+
"""We are directly updating the vat in the products, therefore we have no return value."""
|
|
77
|
+
for product in products.values():
|
|
78
|
+
product.vat = product.price * vat_country_in_percent / 100.0
|
|
79
|
+
```
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
# Openmodule Commands
|
|
2
|
+
|
|
3
|
+
[TOC]
|
|
4
|
+
|
|
2
5
|
We provide multiple commands that are helpful for developing openmodule services.
|
|
3
6
|
|
|
4
7
|
## Create new commands
|
|
@@ -12,6 +15,6 @@ Creating new commands is very simple:
|
|
|
12
15
|
## Translations
|
|
13
16
|
|
|
14
17
|
Commands for creating translations, for more info see [here](translation.md)
|
|
15
|
-
* **openmodule_makemessage:** Creates the translation files and opens
|
|
16
|
-
* **openmodule_translate:** Opens
|
|
17
|
-
* **openmodule_checktranslation:** Checks if the translations are up
|
|
18
|
+
* **openmodule_makemessage:** Creates the translation files and opens an editor for translating
|
|
19
|
+
* **openmodule_translate:** Opens an editor for translating
|
|
20
|
+
* **openmodule_checktranslation:** Checks if the translations are up-to-date and if any translations are empty
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# ConnectionStatusListener
|
|
2
2
|
|
|
3
|
+
[TOC]
|
|
4
|
+
|
|
3
5
|
For some functionality we need to know if we have an active connection to the server or in the case of bridged installations if we have a connection to the main compute unit.
|
|
4
6
|
For this you can use the ConnectionStatusListener, which will be automatically created in the core.
|
|
5
7
|
|
|
@@ -11,7 +13,7 @@ The connection to the server has 4 different states:
|
|
|
11
13
|
* **offline:** The connection is inactive for some time
|
|
12
14
|
* **startup:** We just left the offline state with an active connection
|
|
13
15
|
|
|
14
|
-
The bridge status only
|
|
16
|
+
The bridge status only consists of 2 different states:
|
|
15
17
|
* **online:** Connection to the main compute unit
|
|
16
18
|
* **offline:** No connection to the main compute unit
|
|
17
19
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# CSV Exporter
|
|
2
2
|
|
|
3
|
+
[TOC]
|
|
4
|
+
|
|
3
5
|
The file `utils/csv_export.py` contains a `render` function that can be used to export a list of objects or dicts to a
|
|
4
6
|
csv file.
|
|
5
7
|
Important specifications of the generated csv file:
|
|
@@ -9,7 +11,7 @@ Important specifications of the generated csv file:
|
|
|
9
11
|
* delimiter is `"\t"`
|
|
10
12
|
* line terminator is `"\r\n"`.
|
|
11
13
|
|
|
12
|
-
Important
|
|
14
|
+
** ⚠ Important:** `None` values are converted to empty strings.
|
|
13
15
|
|
|
14
16
|
## Usage
|
|
15
17
|
|
|
@@ -151,3 +153,8 @@ def main():
|
|
|
151
153
|
# we create an export on startup, because you can check the export and the cronjob overwrites it anyway
|
|
152
154
|
tasks.create_export()
|
|
153
155
|
```
|
|
156
|
+
|
|
157
|
+
## Uploading a file
|
|
158
|
+
|
|
159
|
+
For uploading files into the Cloud the Databox service is used.
|
|
160
|
+
You can find the documentation of the databox service [here](utils.md?#databox-upload)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# Database
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
[TOC]
|
|
4
|
+
|
|
5
|
+
On the device we use `sqlalchemy` for our database, additionally we use `alembic` for our migrations. An example of a
|
|
6
|
+
database is included in openmodule-test.
|
|
5
7
|
|
|
6
8
|
## Models
|
|
7
9
|
|
|
@@ -65,16 +67,21 @@ To generate the migration use the provided script `src/database/makemigration.sh
|
|
|
65
67
|
|
|
66
68
|
Afterwards the migrations are created under `src/database/alembic/versions`.
|
|
67
69
|
|
|
68
|
-
###
|
|
70
|
+
### How to migrate
|
|
69
71
|
|
|
70
72
|
The database is always automatically migrated on creation of any database object in the program.
|
|
71
73
|
|
|
74
|
+
**ℹ Information:** Before a migration upgrade is executed a backup of the current database is created.
|
|
75
|
+
|
|
76
|
+
The backup file is stored in the database folder and is named `{service-name}_YYYYmmddHHMMSS.sqlite3.backup`.
|
|
77
|
+
Example: "om_showcase_example_1_20240125123456.sqlite3.backup"
|
|
78
|
+
|
|
72
79
|
### Migration Examples
|
|
73
80
|
|
|
74
81
|
The alembic documentation already has some migration examples and tutorials, but here are some quick tips and pitfalls
|
|
75
82
|
we have encountered.
|
|
76
83
|
|
|
77
|
-
|
|
84
|
+
**⚠ Renaming Columns**
|
|
78
85
|
|
|
79
86
|
When you rename a column, alembic usually creates a new column and drops the old one. It does not know whether you
|
|
80
87
|
actually want a new
|
|
@@ -144,39 +151,44 @@ with database as db:
|
|
|
144
151
|
If an exception is raised during an open database session, all changes will be rolled back.
|
|
145
152
|
It is also possible to create multiple database within a program, but the need to is quite questionable.
|
|
146
153
|
|
|
147
|
-
## Basic
|
|
154
|
+
## Basic database operations
|
|
148
155
|
|
|
149
156
|
Normally sqlalchemy functions should suffice for most jobs. We implemented some additional functionality as functions
|
|
150
157
|
under `openmodule.utils.db_helper`.
|
|
151
158
|
|
|
152
|
-
###
|
|
159
|
+
### Create
|
|
153
160
|
|
|
154
161
|
* db.add(model: DatabaseModel)
|
|
155
162
|
* db.add_all(models: List[DatabaseModel])
|
|
156
163
|
|
|
157
|
-
###
|
|
164
|
+
### Query
|
|
158
165
|
|
|
159
166
|
* base_query = db.query(DatabaseModel)
|
|
160
167
|
* query = base_query..filter_by(**kwargs)
|
|
161
168
|
* query.all() returns a list
|
|
162
169
|
|
|
163
|
-
###
|
|
170
|
+
### Query results
|
|
164
171
|
|
|
165
172
|
* instance = query.one() -> returns element or raises exception if query has more or no elements (MultipleResultsFound,
|
|
166
173
|
NoResultFound)
|
|
167
174
|
* instance = query.first() -> returns first element of query or None
|
|
175
|
+
* query.all() -> return all elements of object
|
|
176
|
+
* query.one() -> returns one element or raises exception if no elements
|
|
177
|
+
* query.one_or_none() -> returns first element or None if no elements, but raises an exception if multiple elements
|
|
178
|
+
* query.get() -> query object with primary key, returns None if not found
|
|
179
|
+
* query.count() -> returns number of elements in query
|
|
168
180
|
|
|
169
|
-
###
|
|
181
|
+
### Update
|
|
170
182
|
|
|
171
183
|
* db.add(model: DatabaseModel) -> previously created model
|
|
172
184
|
* db_helper.update_query(db, query, values: dict)
|
|
173
185
|
|
|
174
|
-
###
|
|
186
|
+
### Delete
|
|
175
187
|
|
|
176
188
|
* db.delete(model: DatabaseModel)
|
|
177
189
|
* db_helper.delete_query(db, query)
|
|
178
190
|
|
|
179
|
-
### Useful query
|
|
191
|
+
### Useful query functions
|
|
180
192
|
|
|
181
193
|
* order_by(*args) -> ordering
|
|
182
194
|
* yield_by(int) -> for batch processing
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Deprecated
|
|
2
|
+
|
|
3
|
+
[TOC]
|
|
4
|
+
|
|
5
|
+
This file holds documentation of deprecated features. It is kept for reference and maybe will be removed in the future.
|
|
6
|
+
|
|
7
|
+
## Deprecated Utils
|
|
8
|
+
|
|
9
|
+
### Api (**DEPRECATED**)
|
|
10
|
+
|
|
11
|
+
We implemented a very basic Api class you can use for http request and that handles errors and authentication. Either
|
|
12
|
+
inherit it or create a class.
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
api = Api(**kwargs)
|
|
16
|
+
try:
|
|
17
|
+
res = api.post("some_url", payload=stuff)
|
|
18
|
+
except ApiException as e:
|
|
19
|
+
if e.retry: # <- makes sense to try again - timeouts or server not available ...
|
|
20
|
+
...
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Backend (**DEPRECATED**)
|
|
24
|
+
|
|
25
|
+
There is also a basic implementation of a backend that provides registration and message passing.
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
class MyAccessService(AccessService):
|
|
29
|
+
def __init__(self):
|
|
30
|
+
super().__init__(implements_session_handling=...)
|
|
31
|
+
...
|
|
32
|
+
|
|
33
|
+
def rpc_check_access(self, request: AccessRequest) -> AccessCheckResponse:
|
|
34
|
+
...
|
|
35
|
+
|
|
36
|
+
# session handling
|
|
37
|
+
def check_in_session(self, message: SessionStartMessage):
|
|
38
|
+
...
|
|
39
|
+
|
|
40
|
+
def check_out_session(self, message: SessionFinishMessage):
|
|
41
|
+
...
|
|
42
|
+
|
|
43
|
+
def session_error_message(self, message: Union[SessionDeleteMessage, SessionIncompleteMessage,
|
|
44
|
+
SessionExitWithoutEntryMessage]):
|
|
45
|
+
...
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Alerting (**DEPRECATED**)
|
|
49
|
+
|
|
50
|
+
The new core also includes an alert handler.
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
core.alerts.send(...)
|
|
54
|
+
alert_id = core.alerts.get_or_add_alert_id(...)
|
|
55
|
+
core.alerts.send_with_alert_id(alert_id, ...)
|
|
56
|
+
```
|