diff --git a/.env.example b/.env.example index b87daf7..46dda2e 100644 --- a/.env.example +++ b/.env.example @@ -61,3 +61,7 @@ RATELIMIT_RATE=150/m # Rate limit (150 requests per minute) RATELIMIT_METHOD=ALL # HTTP methods to rate limit; 'ALL' means all methods RATELIMIT_GROUP=graphql # Group name for the rate limit RATELIMIT_SKIP_TIMEOUT=False # Whether to skip rate limiting during c + + +OPENSEARCH_ADMIN=admin +OPENSEARCH_PASSWORD=B9wc9VrqX7pY \ No newline at end of file diff --git a/.github/workflows/ci_assembly.yml b/.github/workflows/ci_assembly.yml index d2c7e82..75921d3 100755 --- a/.github/workflows/ci_assembly.yml +++ b/.github/workflows/ci_assembly.yml @@ -44,6 +44,21 @@ jobs: --health-interval 10s --health-timeout 5s --health-retries 10 + opensearch: + image: opensearchproject/opensearch:latest + ports: + - 9200:9200 + env: + discovery.type: single-node + cluster.name: my_opensearch_local + http.port: 9200 + plugins.security.ssl.http.enabled: false + OPENSEARCH_INITIAL_ADMIN_PASSWORD: B9wc9VrqX7pY + options: >- + --health-cmd "curl -f -u admin:${OPENSEARCH_INITIAL_ADMIN_PASSWORD} http://localhost:9200/_cluster/health || exit 1" + --health-interval 10s + --health-timeout 5s + --health-retries 10 steps: - uses: actions/checkout@v2 @@ -145,8 +160,8 @@ jobs: SECRET_KEY: secret MODE: DEV DB_DEFAULT: postgresql - CELERY_BROKER_URL": "memory://openIMIS-test//" - CELERY_RESULT_BACKEND": "cache+memory://openIMIS-test//" + CELERY_BROKER_URL: "memory://openIMIS-test//" + CELERY_RESULT_BACKEND: "cache+memory://openIMIS-test//" #DJANGO_SETTINGS_MODULE: hat.settings DB_HOST: localhost DB_PORT: 5432 @@ -156,6 +171,10 @@ jobs: #DEV_SERVER: true SITE_ROOT: api CI_EXCLUDED_MODULE: ${{ vars.CI_EXCLUDED_MODULE }} + OPENSEARCH_ADMIN: admin + OPENSEARCH_PASSWORD: B9wc9VrqX7pY + OPEN_SEARCH_HTTP_PORT: 9200 + OPENSEARCH_HOSTS: "localhost:9200" - name: Django tests MSSQL working-directory: ./openIMIS @@ -171,8 +190,8 @@ jobs: SECRET_KEY: secret MODE: DEV DB_DEFAULT: mssql - CELERY_BROKER_URL": "memory://openIMIS-test//" - CELERY_RESULT_BACKEND": "cache+memory://openIMIS-test//" + CELERY_BROKER_URL: "memory://openIMIS-test//" + CELERY_RESULT_BACKEND: "cache+memory://openIMIS-test//" #DJANGO_SETTINGS_MODULE: hat.settings DB_HOST: localhost DB_PORT: 1433 @@ -183,3 +202,7 @@ jobs: SITE_ROOT: api #REMOTE_USER_AUTHENTICATION: False CI_EXCLUDED_MODULE: ${{ vars.CI_EXCLUDED_MODULE }} + OPENSEARCH_ADMIN: admin + OPENSEARCH_PASSWORD: B9wc9VrqX7pY + OPEN_SEARCH_HTTP_PORT: 9200 + OPENSEARCH_HOSTS: "localhost:9200" diff --git a/.github/workflows/ci_module.yml b/.github/workflows/ci_module.yml index b13567c..d061c2a 100755 --- a/.github/workflows/ci_module.yml +++ b/.github/workflows/ci_module.yml @@ -50,8 +50,32 @@ jobs: - name: Pull openIMIS Backend run: | - rm ./openimis -rf - git clone --depth=1 --branch=${{ inputs.branchName }} https://github.com/openimis/openimis-be_py.git ./openimis + # Determine the target branch + if [ "${{ github.event_name }}" == "pull_request" ]; then + TARGET_BRANCH="${{ github.event.pull_request.base.ref }}" + else + TARGET_BRANCH="${{ github.event.ref }}" + TARGET_BRANCH=${TARGET_BRANCH#refs/heads/} + fi + + # Use 'develop' as fallback if TARGET_BRANCH is empty or not a release branch + if [[ -z "$TARGET_BRANCH" ]]; then + TARGET_BRANCH="develop" + fi + + echo "Target branch: $TARGET_BRANCH" + + # Clone the repository + rm -rf ./openimis + git clone --depth=1 --branch=$TARGET_BRANCH https://github.com/openimis/openimis-be_py.git ./openimis || { + echo "Failed to clone $TARGET_BRANCH, falling back to develop" + git clone --depth=1 --branch=develop https://github.com/openimis/openimis-be_py.git ./openimis + } + + # Verify the cloned branch + cd ./openimis + CLONED_BRANCH=$(git rev-parse --abbrev-ref HEAD) + echo "Cloned branch: $CLONED_BRANCH" - name: Copy Current branch uses: actions/checkout@v2 @@ -124,6 +148,22 @@ jobs: runs-on: ubuntu-20.04 needs: build_backend services: + opensearch: + image: opensearchproject/opensearch:latest + ports: + - 9200:9200 + env: + discovery.type: single-node + cluster.name: my_opensearch_local + http.port: 9200 + plugins.security.ssl.http.enabled: false + OPENSEARCH_INITIAL_ADMIN_PASSWORD: B9wc9VrqX7pY + options: >- + --health-cmd "curl -f -u admin:${OPENSEARCH_INITIAL_ADMIN_PASSWORD} http://localhost:9200/_cluster/health || exit 1" + --health-interval 10s + --health-timeout 5s + --health-retries 10 + mssql: image: mcr.microsoft.com/mssql/server:2017-latest env: @@ -228,11 +268,30 @@ jobs: #REMOTE_USER_AUTHENTICATION: False CI_EXCLUDED_MODULE: ${{ vars.CI_EXCLUDED_MODULE }} MODE: DEV + OPENSEARCH_ADMIN: admin + OPENSEARCH_PASSWORD: B9wc9VrqX7pY ci_module_psql_test_module_only: name: Run Module Tests (PSQL) runs-on: ubuntu-20.04 needs: build_backend services: + opensearch: + image: opensearchproject/opensearch:latest + ports: + - 9200:9200 + env: + discovery.type: single-node + cluster.name: my_opensearch_local + http.port: 9200 + plugins.security.ssl.http.enabled: false + OPENSEARCH_INITIAL_ADMIN_PASSWORD: B9wc9VrqX7pY + options: >- + --health-cmd "curl -f -u admin:${OPENSEARCH_INITIAL_ADMIN_PASSWORD} http://localhost:9200/_cluster/health || exit 1" + --health-interval 10s + --health-timeout 5s + --health-retries 10 + + pgsql: image: postgres env: @@ -332,11 +391,31 @@ jobs: SITE_ROOT: api CI_EXCLUDED_MODULE: ${{ vars.CI_EXCLUDED_MODULE }} MODE: DEV + OPENSEARCH_ADMIN: admin + OPENSEARCH_PASSWORD: B9wc9VrqX7pY + OPENSEARCH_HOSTS: "localhost:9200" ci_module_psql_test: name: Run All Tests (PSQL) runs-on: ubuntu-20.04 needs: build_backend services: + opensearch: + image: opensearchproject/opensearch:latest + ports: + - 9200:9200 + env: + discovery.type: single-node + cluster.name: my_opensearch_local + http.port: 9200 + plugins.security.ssl.http.enabled: false + OPENSEARCH_INITIAL_ADMIN_PASSWORD: B9wc9VrqX7pY + options: >- + --health-cmd "curl -f -u admin:${OPENSEARCH_INITIAL_ADMIN_PASSWORD} http://localhost:9200/_cluster/health || exit 1" + --health-interval 10s + --health-timeout 5s + --health-retries 10 + + pgsql: image: postgres env: @@ -435,6 +514,9 @@ jobs: SITE_ROOT: api CI_EXCLUDED_MODULE: ${{ vars.CI_EXCLUDED_MODULE }} MODE: DEV + OPENSEARCH_ADMIN: admin + OPENSEARCH_PASSWORD: B9wc9VrqX7pY + OPENSEARCH_HOSTS: "localhost:9200" - name: Generate Coverage Report if: always() working-directory: ./openimis/openIMIS @@ -492,7 +574,7 @@ jobs: # Flake8 Report export MODULE_NAME="$(echo $GITHUB_REPOSITORY | sed 's#^openimis/openimis-be-\(.*\)_py$#\1#')" MOD_DIR="../current-module/$MODULE_NAME" - python -m flake8 --output-file=flake8-report.txt $MOD_DIR --exit-zero + python -m flake8 --output-file=flake8-report.txt $MOD_DIR --exit-zero --ignore W503 sed -i 's|\.\./current-module/||g' flake8-report.txt python -m flake8 $MOD_DIR diff --git a/.vscode/launch.json b/.vscode/launch.json index 274fe3c..2224202 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -21,6 +21,7 @@ "product", "insuree", "policy", + "calcrule_validations", "contribution", "payer", "payment", @@ -213,6 +214,7 @@ "opensearch_reports", "payment_cycle", "calcrule_social_protection", + "calcrule_validations", "payroll" ], "django": true, diff --git a/README.md b/README.md index 8390317..0cfacd3 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,72 @@ # Environment Variables -| ENV | Values | Description | +| ENV | Values | Description | | --------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| MODE | DEV, PROD | This is the mode of running the application. There are 2 modes available. DEV for the Development mode and PROD for the production mode. Certain settings will be changed according to the mode. Such as in the PROD mode, mutation will run asynchronously and synchronously otherwise. Same applies to DEBUG, it will be OFF in PROD and TRUE otherwise. | -| DB_ENGINE | django.db.backends.postgresql, mssql | Currently openIMIS supports 2 databases, as the values suggested, postgres and mssql. | -| DEMO_DATASET | true | Define if the database should be initiated with demo dataset. Comment for empty database. | -| DB_DEFAULT | String | String This variables sets the default database engine for the system. Possible values: postgresql, mssql. Default: postgresql. | -| DB_HOST | String | Define the name of your database server | -| DB_PORT | Integer | Define the port on which your database accepts the connection | -| DB_NAME | String | Define the name of the openIMIS database | -| DB_USER | String | Configure the username with which you want to connect to the database | -| DB_PASSWORD | String | Configure the database password | -| DB_TEST_NAME | String | If you are developing unit tests then this setting will create the testing database as per the name set | -| NO_DATABASE | true, false | If set to true, it will use sqlite.db3 as a database | -| DB_OPTIONS | String | Define any additional database options | -| PSQL_DB_ENGINE | String | Define a library to use to connect with postgres database. Default value is django.db.backends.postgresql | -| MSSQL_DB_ENGINE | String | Define a library to use to connect with MS SQL database Default value is mssql. | -| SITE_ROOT | String | Site root that will prefix all exposed endpoints. It's required when working with openIMIS frontend. For example, if the value is set `api` then the endpoint will appear like `your_domain_name/api/xxx` | -| DJANGO_LOG_LEVEL | INFO, WARNING, ERROR, DEBUG | Define the level of logs | -| DJANGO_LOG_HANDLER | console, debug-log | Depending on the value set, application will print the logs | -| DJANGO_DB_LOG_HANDLER | console, debug-log | Depending on the value set, application will print the logs | -| PHOTO_ROOT_PATH | String | Define the path for the photos of insurees. This setting is used in the Insuree module. The value set here will be overwritten by the InsureeConfig file. | -| DJANGO_MIGRATE | True, False | Based on the value set, application runs the migration command before starting up. If the SITE_ROOT value is set to api then the migration will always run regardless of the value | -| SCHEDULER_AUTOSTART | True, False | All the modules will be searched for the scheduled tasks, if the value is set to True | -| OPENSEARCH_HOST | String | Define the opensearch host | -| OPENSEARCH_ADMIN | String | Define the login name for open search | -| OPENSEARCH_PASSWORD | String | Define the admin password to login to open search | -| BE_BRANCH | String | Define the github branch for the Backend form which you wan to install the module. Default is develop. | -| FE_BRANCH | String | Define the github branch for the Front-end form which you wan to install the module. Default is develop. | -| DB_BRANCH | String | Define the github branch for the Database form which you wan to install the module. Default is develop. | -| ALLOWED_HOST | Comma separated String | Define the list of allowed hosts such as IP addresses or Domain names to access the application. If the value is not set it will allow all the IP addresses. | -| LOKALISE_APIKEY | String | Set the lokalise api key. Obtain this key form the lokalise project to be able to use the lokalise-upload | -| OPENIMIS_CONF_JSON | String | Define the path for the openimis config file. If not set the default config from the root folder will be taken. | -| DB_QUERIES_LOG_FILE | String | Define the path of the file to save the database queries. Default is db-queries.log | -| DEBUG_LOG_FILE | String | Define the path of the file to save the debug log. Default is debug.log | -| SENTRY_DSN | String | Set the unique Sentry DSN. This can be obtained from your Sentry account dashboard | -| SENTRY_SAMPLE_RATE | 0-1 | This configuration allows you to to control the rate at which traces are collected. Values are between 0 and 1. 0 means no traces will be collected (tracing is disabled). 1 means traces will be collected for every request. Any value between 0 and 1 represents the probability of capturing trace. For instance, a value 0.3 means that approximately 30% of requests will have traces collected. | -| IS_SENTRY_ENABLED | True, False | Defines if the Sentry error tracking and monitoring functionality is enabled or disabled. | -| SITE_URL | String | Define the base url. This is used to create links in FHIR module | -| SECRET_KEY | String | This is used internally by Django. Make sure to set it up in production server. | -| REMOTE_USER_AUTHENTICATION | true, false | Set it to true if you want to enable the RemoteUserBackend as an authentication backend in Django. By default it's false | -| CELERY_BROKER_URL | String | Define a message broker url for celery. Default value is amqp://rabitmq | -| CHANNELS_HOST | String | Set the host for the Django Channel. Default value is amqp://guest:guest@127.0.0.1/ | -| EMAIL_HOST | String | Define an Email Host. Default value is localhost | -| EMAIL_PORT | Integer | Define a valid port for the email server | -| EMAIL_HOST_USER | String | Set the username to send emails | -| EMAIL_HOST_PASSWORD | String | Set the password for the email | -| EMAIL_USE_TLS | True, False | Configure the TLS setting. Default value is False | -| EMAIL_USE_SSL | True, False | Configure the SSL settings for the emails. Default value is False | -| DATA_UPLOAD_MAX_MEMORY_SIZE | Integer | Define the upload size allowed in **bytes** via the POST request. Default is 10 MB | -| MASTER_DATA_PASSWORD | String | This setting is used in exporting entities. Configure the password to zip the exported entities. | -| FRONTEND_URL | String | Define the URL to access the front-end | -| DJANGO_SETTINGS_MODULE | String | Define the python import path to settings module for Django project. By default it is set to openIMIS.settings | -| OPEHNHIM_URL | String | This setting is used in fhir module. Define the url for openHIM | -| OPEHNHIM_USER | String | This setting is used in fhir module. Define the user for openHIM | -| OPEHNHIM_PASSWORD | String | This setting is used in fhir module. Define the password for openHIM | -| OPENIMIS_CONF | String | Define a path to the config file. By default it reads from ../openimis.json | -| CLAIMDOC_TOKEN | String | Used in backend caching. Define a token to communicate with the remote server. Default is set to 'TestToken' | -| CACHE_BACKEND | String | Specifies the [caching backend](https://docs.djangoproject.com/en/5.0/topics/cache/#setting-up-the-cache) to be used. Default is set to PyMemcached. | -| CACHE_URL | String | Defines the location of the cache backend. Default is `unix:/tmp/memcached.sock` for a Unix socket connection. | -| CACHE_OPTIONS | String | A JSON string representing a dictionary of additional options passed to the cache backend. Empty by default | -| RATELIMIT_CACHE | String | The cache alias to use for rate limiting. Defaults to `default`. | -| RATELIMIT_KEY | String | Key to identify the client for rate limiting; `ip` means it will use the client's IP address. Defaults to `ip`. | -| RATELIMIT_RATE | String | Rate limit value (e.g., `150/m` for 150 requests per minute). Defaults to `150/m`. | -| RATELIMIT_METHOD | String | HTTP methods to rate limit; `ALL` means all methods. Defaults to `ALL`. | -| RATELIMIT_GROUP | String | Group name for the rate limit. Defaults to `graphql`. | -| RATELIMIT_SKIP_TIMEOUT | Boolean | Whether to skip rate limiting during cache timeout. Defaults to `False`. | -| CSRF_TRUSTED_ORIGINS | String | Define the trusted origins for CSRF protection, separated by commas. Defaults to `http://localhost:3000,http://localhost:8000`. | +| MODE | DEV, PROD | This is the mode of running the application. There are 2 modes available. DEV for the Development mode and PROD for the production mode. Certain settings will be changed according to the mode. Such as in the PROD mode, mutation will run asynchronously and synchronously otherwise. Same applies to DEBUG, it will be OFF in PROD and TRUE otherwise. | +| DB_ENGINE | django.db.backends.postgresql, mssql | Currently openIMIS supports 2 databases, as the values suggested, postgres and mssql. | +| DEMO_DATASET | true | Define if the database should be initiated with demo dataset. Comment for empty database. | +| DB_DEFAULT | String | String This variables sets the default database engine for the system. Possible values: postgresql, mssql. Default: postgresql. | +| DB_HOST | String | Define the name of your database server | +| DB_PORT | Integer | Define the port on which your database accepts the connection | +| DB_NAME | String | Define the name of the openIMIS database | +| DB_USER | String | Configure the username with which you want to connect to the database | +| DB_PASSWORD | String | Configure the database password | +| DB_TEST_NAME | String | If you are developing unit tests then this setting will create the testing database as per the name set| +| NO_DATABASE | true, false | If set to true, it will use sqlite.db3 as a database | +| DB_OPTIONS | String | Define any additional database options | +| PSQL_DB_ENGINE | String | Define a library to use to connect with postgres database. Default value is django.db.backends.postgresql | +| MSSQL_DB_ENGINE | String | Define a library to use to connect with MS SQL database Default value is mssql. | +| SITE_ROOT | String | Site root that will prefix all exposed endpoints. It's required when working with openIMIS frontend. For example, if the value is set `api` then the endpoint will appear like `your_domain_name/api/xxx` | +| DJANGO_LOG_LEVEL | INFO, WARNING, ERROR, DEBUG | Define the level of logs | +| DJANGO_LOG_HANDLER | console, debug-log | Depending on the value set, application will print the logs | +| DJANGO_DB_LOG_HANDLER | console, debug-log | Depending on the value set, application will print the logs | +| PHOTO_ROOT_PATH | String | Define the path for the photos of insurees. This setting is used in the Insuree module. The value set here will be overwritten by the InsureeConfig file. | +| DJANGO_MIGRATE | True, False | Based on the value set, application runs the migration command before starting up. If the SITE_ROOT value is set to api then the migration will always run regardless of the value | +| SCHEDULER_AUTOSTART | True, False | All the modules will be searched for the scheduled tasks, if the value is set to True | +| OPENSEARCH_HOSTS | String | Define the opensearch hosts, comma separated http://opensearch:9200 | +| OPENSEARCH_ADMIN | String | Define the login name for open search | +| OPENSEARCH_PASSWORD | String | Define the admin password to login to open search | +| BE_BRANCH | String | Define the github branch for the Backend form which you wan to install the module. Default is develop. | +| FE_BRANCH | String | Define the github branch for the Front-end form which you wan to install the module. Default is develop. | +| DB_BRANCH | String | Define the github branch for the Database form which you wan to install the module. Default is develop.| | +| LOKALISE_APIKEY | String | Set the lokalise api key. Obtain this key form the lokalise project to be able to use the lokalise-upload | +| OPENIMIS_CONF_JSON | String | Define the path for the openimis config file. If not set the default config from the root folder will be taken. | +| DB_QUERIES_LOG_FILE | String | Define the path of the file to save the database queries. Default is db-queries.log | +| DEBUG_LOG_FILE | String | Define the path of the file to save the debug log. Default is debug.log | +| SENTRY_DSN | String | Set the unique Sentry DSN. This can be obtained from your Sentry account dashboard | +| SENTRY_SAMPLE_RATE | 0-1 | This configuration allows you to to control the rate at which traces are collected. Values are between 0 and 1. 0 means no traces will be collected (tracing is disabled). 1 means traces will be collected for every request. Any value between 0 and 1 represents the probability of capturing trace. For instance, a value 0.3 means that approximately 30% of requests will have traces collected. | +| IS_SENTRY_ENABLED | True, False | Defines if the Sentry error tracking and monitoring functionality is enabled or disabled. | +| SITE_URL | String | Define the base url. This is used to create links in FHIR module | +| SITE_FRONT | String | Define base uri for the frontend| +| FRONTEND_URL | String | Define the frontend URL if not aligned with SITE_URL/SITE_FRONT| +| SECRET_KEY | String | This is used internally by Django. Make sure to set it up in production server. | +| REMOTE_USER_AUTHENTICATION | true, false | Set it to true if you want to enable the RemoteUserBackend as an authentication backend in Django. By default it's false | +| CELERY_BROKER_URL | String | Define a message broker url for celery. Default value is amqp://rabitmq | +| CHANNELS_HOST | String | Set the host for the Django Channel. Default value is amqp://guest:guest@127.0.0.1/ | +| EMAIL_HOST | String | Define an Email Host. Default value is localhost | +| EMAIL_PORT | Integer | Define a valid port for the email server | +| EMAIL_HOST_USER | String | Set the username to send emails | +| EMAIL_HOST_PASSWORD | String | Set the password for the email | +| EMAIL_USE_TLS | True, False | Configure the TLS setting. Default value is False | +| EMAIL_USE_SSL | True, False | Configure the SSL settings for the emails. Default value is False | +| DATA_UPLOAD_MAX_MEMORY_SIZE | Integer | Define the upload size allowed in **bytes** via the POST request. Default is 10 MB | +| MASTER_DATA_PASSWORD | String | This setting is used in exporting entities. Configure the password to zip the exported entities. | +| DJANGO_SETTINGS_MODULE | String | Define the python import path to settings module for Django project. By default it is set to openIMIS.settings | +| OPEHNHIM_URL | String | This setting is used in fhir module. Define the url for openHIM | +| OPEHNHIM_USER | String | This setting is used in fhir module. Define the user for openHIM | +| OPEHNHIM_PASSWORD | String | This setting is used in fhir module. Define the password for openHIM | +| OPENIMIS_CONF | String | Define a path to the config file. By default it reads from ../openimis.json| +| CLAIMDOC_TOKEN | String | Used in backend caching. Define a token to communicate with the remote server. Default is set to 'TestToken' | +| CACHE_BACKEND | String | Specifies the [caching backend](https://docs.djangoproject.com/en/5.0/topics/cache/#setting-up-the-cache) to be used. Default is set to PyMemcached. | +| CACHE_URL | String | Defines the location of the cache backend. Default is `unix:/tmp/memcached.sock` for a Unix socket connection. | +| CACHE_OPTIONS | String | A JSON string representing a dictionary of additional options passed to the cache backend. Empty by default | +| RATELIMIT_CACHE | String | The cache alias to use for rate limiting. Defaults to `default`. | +| RATELIMIT_KEY | String | Key to identify the client for rate limiting; `ip` means it will use the client's IP address. Defaults to `ip`. | +| RATELIMIT_RATE | String | Rate limit value (e.g., `150/m` for 150 requests per minute). Defaults to `150/m`. | +| RATELIMIT_METHOD | String | HTTP methods to rate limit; `ALL` means all methods. Defaults to `ALL`. | +| RATELIMIT_GROUP | String | Group name for the rate limit. Defaults to `graphql`. | +| RATELIMIT_SKIP_TIMEOUT | Boolean | Whether to skip rate limiting during cache timeout. Defaults to `False`. | +| HOSTS | String | Define the trusted domains that are used for PROD CORS and CSRF protection, separated by commas. Defaults to `localhost, 192.168.0.1`. | ## Developers setup @@ -78,61 +78,61 @@ When programming for openIMIS backend, you are highly encouraged to use the feat - install python 3, recommended in a [venv](https://docs.python.org/3/library/venv.html) or [virtualenv](https://virtualenv.pypa.io) - install [pip](https://pip.pypa.io) - within `openimis-be_py` directory - - install openIMIS (external) dependencies: `pip install -r requirements.txt`. For development workstations, one can use `pip install -r dev-requirements.txt` instead, for more modules. - - In the script directory, - - generate the openIMIS modules dependencies file (from openimis.json config): `python modules-requirements.py openimis.json > modules-requirements.txt` - - if you previously installed openIMIS on another version, it seems safe to uninstall all previous modules-requirement to be sure it match current version `pip uninstall -r modules-requirements.txt` - - install openIMIS current modules: `pip install -r modules-requirements.txt` - - Copy the example environment setup and adjust the settings (like database connection): `cp .env.example .env`. - Refer to .env.example or the Environment Variable tables above for more info. + - install openIMIS (external) dependencies: `pip install -r requirements.txt`. For development workstations, one can use `pip install -r dev-requirements.txt` instead, for more modules. + - In the script directory, + - generate the openIMIS modules dependencies file (from openimis.json config): `python modules-requirements.py openimis.json > modules-requirements.txt` + - if you previously installed openIMIS on another version, it seems safe to uninstall all previous modules-requirement to be sure it match current version `pip uninstall -r modules-requirements.txt` + - install openIMIS current modules: `pip install -r modules-requirements.txt` + - Copy the example environment setup and adjust the settings (like database connection): `cp .env.example .env`. + Refer to .env.example or the Environment Variable tables above for more info. - start openIMIS from within `openimis-be_py/openIMIS`: `python manage.py runserver` At this stage, you may (depends on the database you connect to) need to: - apply django migrations, from `openimis-be_py/openIMIS`: `python manage.py migrate` - create a superuser for django admin console, from - `openimis-be_py/openIMIS`: `python manage.py createsuperuser` (will - not prompt for a password) and then `python manage.py changepassword + `openimis-be_py/openIMIS`: `python manage.py createsuperuser` (will + not prompt for a password) and then `python manage.py changepassword ` ### To edit (modify) an existing openIMIS module (e.g. `openimis-be-claim`) - checkout the module's git repo NEXT TO (not within!) `openimis-be_py` directory and create a git branch for your changes - from `openimis-be_py` - - uninstall the packaged module you want to work on (example: openimis-be-claim): `pip uninstall openimis-be-claim` - - install the 'local' version of the module: `pip install -e ../openimis-be-claim_py/` + - uninstall the packaged module you want to work on (example: openimis-be-claim): `pip uninstall openimis-be-claim` + - install the 'local' version of the module: `pip install -e ../openimis-be-claim_py/` - from here on, openIMIS is using the local content of the module (with live update) ### To create a new openIMIS module (e.g. `openimis-be-mymodule`) - create a (git-enabled) directory next to the other modules, with a subdirectory named as your module 'logical' name: `/openimis-be-mymodule_py/mymodule` - from `/openimis-be_py/openIMIS`: - - create the module skeleton: `python manage.py startapp mymodule ../../openimis-be-mymodule_py/mymodule` - - prepare your module to be mounted via pip: create and complete the `/openimis-be-mymodule_py/setup.py` (and README.md,... files) - - every openIMIS module must provide its urlpatterns (even if empty): - - create the file `/openimis-be-mymodule_py/mymodule/urls.py` - - with content: `urlpatterns = []` - - register your module in the pip requirements of openIMIS, referencing your 'local' codebase: `pip install -e ../../openimis-be-mymodule_py/` - - register your module to openIMIS django site in `/openimis-be_py/openimis.json` + - create the module skeleton: `python manage.py startapp mymodule ../../openimis-be-mymodule_py/mymodule` + - prepare your module to be mounted via pip: create and complete the `/openimis-be-mymodule_py/setup.py` (and README.md,... files) + - every openIMIS module must provide its urlpatterns (even if empty): + - create the file `/openimis-be-mymodule_py/mymodule/urls.py` + - with content: `urlpatterns = []` + - register your module in the pip requirements of openIMIS, referencing your 'local' codebase: `pip install -e ../../openimis-be-mymodule_py/` + - register your module to openIMIS django site in `/openimis-be_py/openimis.json` - from here on, your local openIMIS has a new module, directly loaded from your directory. ### To create a distinct implementation of an existing openIMIS module (e.g. `openimis-be-location-dhis2`) - from `openimis-be_py`, uninstall the packaged module you want to replace: `pip uninstall openimis-be-location` - follow the same procedure as for a brand new openIMIS module, - ... but give it the same logical name as the one you want to replace: `/openimis-be-location-dhis2_py/location` + ... but give it the same logical name as the one you want to replace: `/openimis-be-location-dhis2_py/location` ### To manage translations of your module - from your module root dir, execute '../openimis-be_py/script/gettext.sh' - ... this extract all your translations keys from your code into your module root dir/locale/en/LC_MESSAGES/django.po + ... this extract all your translations keys from your code into your module root dir/locale/en/LC_MESSAGES/django.po - you may want to provide translation in generated django.po file... or manage them via lokalize (need to upload the keys,...) ### To run unit tests on a module (example openimis-be-claim) - from `openimis-be_py` - - (re)initialize test database (at this stage structure is not managed by django): - - launch unit tests, with the 'keep database' option: `python + - (re)initialize test database (at this stage structure is not managed by django): + - launch unit tests, with the 'keep database' option: `python manage.py test --keep claim` ### To get profiler report (DEBUG mode only) @@ -144,7 +144,7 @@ In request query include additional parameters: #### Example: -`http://localhost:8000/api/graphql?prof=True&download=True` +`http://localhost:8000/api/graphql?prof=True&download=True` creates profiler report for execution of query/mutation defined in request's POST body. ### To publish (in PyPI) the modified (or new) module @@ -152,8 +152,8 @@ creates profiler report for execution of query/mutation defined in request's POS - adapt the `openimis-be-mymodule_py/setup.py` to (at least) bump version number (e.g. 1.2.3) - commit your changes to the git repo and merge into master - tag the git repo according to your new version number: - - `git tag -a v1.2.3 -m "v1.2.3"` - - `git push --tags` + - `git tag -a v1.2.3 -m "v1.2.3"` + - `git push --tags` - create the PyPI package (can be automated on a ci-build): `python setup.py bdist_wheel` - upload the created package (in `dist/`) to PyPI.org: `twine upload -r pypi dist/openimis_be_mymodule-1.2.3*` @@ -166,12 +166,12 @@ Note: as a distributor, you may want to run an openIMIS version without docker. - clone this repo (creates the `openimis-be_py` directory) and create a git branch (named according to the release you want to bundle) - adapt the `openimis-be_py/openimis.json` to specify the modules (and their versions) to be bundled - make release candidates docker image from `openimis-be_py/`: `docker build . -t openimis-be-2.3.4 [--build-arg="DB_DEFAULT=postgresql"]` - - change the version (openimis-be-2.3.4) to the actual version you want to build - - if only postgresql database is used, include the build-arg argument + - change the version (openimis-be-2.3.4) to the actual version you want to build + - if only postgresql database is used, include the build-arg argument - configure the database connection (see section here below) - run the docker image, referring to environment variables file: `docker run --env-file .env openimis-be-2.3.4` - Note: when starting, the docker image will automatically apply the necessary database migrations to - the database + Note: when starting, the docker image will automatically apply the necessary database migrations to + the database When release candidate is accepted: @@ -183,11 +183,11 @@ When release candidate is accepted: - clone this repo (creates the `openimis-be_py` directory) and create a git branch (named according to the release you want to bundle) - adapt the `openimis-be_py/openimis.json` to specify the modules (and their versions) to be bundled, the "pip" params can be: - - standard pip: `openimis-be-core==1.2.0rc1` - - from local: `-e ../openimis-be-core_py` - - from git: `git+https://github.com/openimis/openimis-be-core_py.git@develop` - - the egg can be specified so pip know what to look `git+https://github.com/openimis/openimis-be-core_py.git@develop#egg=openimis-be-core` - - from tarball: `https://github.com/openimis/openimis-be_py/archive/v1.1.0.tar.gz` + - standard pip: `openimis-be-core==1.2.0rc1` + - from local: `-e ../openimis-be-core_py` + - from git: `git+https://github.com/openimis/openimis-be-core_py.git@develop` + - the egg can be specified so pip know what to look `git+https://github.com/openimis/openimis-be-core_py.git@develop#egg=openimis-be-core` + - from tarball: `https://github.com/openimis/openimis-be_py/archive/v1.1.0.tar.gz` - (required only once)`python -m venv ./venv`: create the python venv - `./venv/Script/activate[.sh/.ps1]`: Activate the venv - `python script/modules-requirements.py openimis.json > modules-requirements.txt`: list the source of the module to install @@ -201,146 +201,146 @@ When release candidate is accepted: The configuration for connection to the database is identical for developers and distributors: - By default, openIMIS is connected to MS-SQL Server: - - via ODBC (and pyodbc) driver - - using TCP/IP protocol (with server DNS name as hostname... or localhost) and fixed port (leave `DB_PORT` here below empty for dynamic port) - - SQL Server (not Windows/AD) authentication (user name password managed in SQL Server admin) - Download and install the ODBC that correspond to your OS and MS-SQL Server version (https://docs.microsoft.com/en-us/sql/connect/odbc/) + - via ODBC (and pyodbc) driver + - using TCP/IP protocol (with server DNS name as hostname... or localhost) and fixed port (leave `DB_PORT` here below empty for dynamic port) + - SQL Server (not Windows/AD) authentication (user name password managed in SQL Server admin) + Download and install the ODBC that correspond to your OS and MS-SQL Server version (https://docs.microsoft.com/en-us/sql/connect/odbc/) - Copy the example environment setup and adjust the variables: `cp .env.example .env`. Refer to .env.example for more info. - ``` - DB_HOST=mssql-host-server - DB_PORT=mssql-port - DB_NAME=database-name - DB_USER=database-user - DB_PASSWORD=database-password - ``` - Notes: + ``` + DB_HOST=mssql-host-server + DB_PORT=mssql-port + DB_NAME=database-name + DB_USER=database-user + DB_PASSWORD=database-password + ``` + Notes: - instead of `.env` file, you can use environment variables (e.g. provided as parameters in the docker-compose.yml) - default used django database 'engine' in openIMIS is - `sql_server.pyodbc`. If you need to use another one, use the `DB_ENGINE` entry in the `.env` file + `sql_server.pyodbc`. If you need to use another one, use the `DB_ENGINE` entry in the `.env` file - default 'options' in openIMIS are `{'driver': 'ODBC Driver 17 for SQL Server','unicode_results': True}` - If you need to provide other options, use the `DB_OPTIONS` entry in the `.env` file (be complete: the new json string will entirely replace the default one) + If you need to provide other options, use the `DB_OPTIONS` entry in the `.env` file (be complete: the new json string will entirely replace the default one) ## Developer tools ### To create backend module skeleton in single command - from `/openimis-be_py/openIMIS`: - - run this command: `python manage.py create_openimis_module [--template