Skip to content

Commit

Permalink
Release 2023.03.2 (#1341)
Browse files Browse the repository at this point in the history
  • Loading branch information
angela-tran committed Mar 30, 2023
2 parents df6f0e8 + 35f5b27 commit d48a448
Show file tree
Hide file tree
Showing 27 changed files with 109 additions and 170 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests-ui.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
docker compose up --detach client
- name: Run Lighthouse tests for a11y
uses: treosh/lighthouse-ci-action@9.3.1
uses: treosh/lighthouse-ci-action@9.6.8
with:
urls: |
http://localhost:8000
Expand Down
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
*.mo
*.tfbackend
*.tmp
benefits/core/migrations/0002_*.py
!benefits/core/migrations/0002_sample_data.py
static/
!benefits/static
benefits/static/sha.txt
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ repos:
- python

- repo: https://github.com/pycqa/bandit
rev: 1.7.4
rev: 1.7.5
hooks:
- id: bandit
args: ["-ll"]
Expand Down
3 changes: 1 addition & 2 deletions appcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ COPY manage.py manage.py
COPY bin/ bin/
COPY benefits/ benefits/

# ensure $USER can compile messages in the locale directories and copy migration files from $DJANGO_MIGRATIONS_DIR
# ensure $USER can compile messages in the locale directories
USER root
RUN chmod -R 777 benefits/locale
RUN chmod -R 777 benefits/core/migrations
USER $USER

# configure container executable
Expand Down
2 changes: 1 addition & 1 deletion appcontainer/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ Django==4.1.7
django-csp==3.7
eligibility-api==2023.01.1
requests==2.28.2
sentry-sdk==1.16.0
sentry-sdk==1.17.0
six==1.16.0
2 changes: 1 addition & 1 deletion benefits/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__version__ = "2023.03.1"
__version__ = "2023.03.2"

VERSION = __version__
7 changes: 6 additions & 1 deletion benefits/core/analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,12 @@ def send(self, event):
payload = self._payload(event)
logger.debug(f"Sending event payload: {payload}")

r = requests.post(self.url, headers=self.headers, json=payload)
r = requests.post(
self.url,
headers=self.headers,
json=payload,
timeout=settings.REQUESTS_TIMEOUT,
)
if r.status_code == 200:
logger.debug(f"Event sent successfully: {r.json()}")
elif r.status_code == 400:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
"""Data migration which loads sample data.
Set environment variable DJANGO_LOAD_SAMPLE_DATA to False to skip loading sample data.
"""Data migration which loads configuration data for Benefits.
"""
import json
import os

from django.conf import settings
from django.db import migrations
from django.utils.translation import gettext_lazy as _


def load_sample_data(app, *args, **kwargs):
if not settings.LOAD_SAMPLE_DATA:
print(" LOAD_SAMPLE_DATA is set to False, skipping sample data")
return

def load_data(app, *args, **kwargs):
EligibilityType = app.get_model("core", "EligibilityType")

mst_senior_type = EligibilityType.objects.create(
Expand Down Expand Up @@ -260,7 +254,7 @@ def load_sample_data(app, *args, **kwargs):
merchant_id=os.environ.get("SACRT_AGENCY_MERCHANT_ID", "sacrt"),
info_url="https://sacrt.com/",
phone="916-321-2877",
active=True,
active=os.environ.get("SACRT_AGENCY_ACTIVE", "True").lower() == "true",
private_key=client_private_key,
public_key=client_public_key,
jws_signing_alg=os.environ.get("SACRT_AGENCY_JWS_SIGNING_ALG", "RS256"),
Expand All @@ -277,5 +271,5 @@ class Migration(migrations.Migration):
]

operations = [
migrations.RunPython(load_sample_data),
migrations.RunPython(load_data),
]
14 changes: 0 additions & 14 deletions benefits/core/migrations/0003_data_migration_order.py

This file was deleted.

3 changes: 2 additions & 1 deletion benefits/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""
import logging

from django.conf import settings
from django.db import models
from django.urls import reverse

Expand Down Expand Up @@ -31,7 +32,7 @@ def data(self):
if self.text:
return self.text
elif self.remote_url:
self.text = requests.get(self.remote_url).text
self.text = requests.get(self.remote_url, timeout=settings.REQUESTS_TIMEOUT).text

self.save()
return self.text
Expand Down
2 changes: 1 addition & 1 deletion benefits/core/recaptcha.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ def verify(form_data: dict) -> bool:
return False

payload = dict(secret=settings.RECAPTCHA_SECRET_KEY, response=form_data[DATA_FIELD])
response = requests.post(settings.RECAPTCHA_VERIFY_URL, payload).json()
response = requests.post(settings.RECAPTCHA_VERIFY_URL, payload, timeout=settings.REQUESTS_TIMEOUT).json()

return bool(response["success"])
34 changes: 31 additions & 3 deletions benefits/enrollment/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from tempfile import NamedTemporaryFile
import time

from django.conf import settings
import requests


Expand Down Expand Up @@ -123,15 +124,42 @@ def _make_url(self, *parts):

def _get(self, url, payload, headers=None):
h = self._headers(headers)
return self._cert_request(lambda verify, cert: requests.get(url, headers=h, params=payload, verify=verify, cert=cert))
return self._cert_request(
lambda verify, cert: requests.get(
url,
headers=h,
params=payload,
verify=verify,
cert=cert,
timeout=settings.REQUESTS_TIMEOUT,
)
)

def _patch(self, url, payload, headers=None):
h = self._headers(headers)
return self._cert_request(lambda verify, cert: requests.patch(url, headers=h, json=payload, verify=verify, cert=cert))
return self._cert_request(
lambda verify, cert: requests.patch(
url,
headers=h,
json=payload,
verify=verify,
cert=cert,
timeout=settings.REQUESTS_TIMEOUT,
)
)

def _post(self, url, payload, headers=None):
h = self._headers(headers)
return self._cert_request(lambda verify, cert: requests.post(url, headers=h, json=payload, verify=verify, cert=cert))
return self._cert_request(
lambda verify, cert: requests.post(
url,
headers=h,
json=payload,
verify=verify,
cert=cert,
timeout=settings.REQUESTS_TIMEOUT,
)
)

def _cert_request(self, request_func):
"""
Expand Down
9 changes: 7 additions & 2 deletions benefits/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,6 @@ def _filter_empty(ls):
}
}

LOAD_SAMPLE_DATA = os.environ.get("DJANGO_LOAD_SAMPLE_DATA", "true").lower() != "false"

# Password validation

AUTH_PASSWORD_VALIDATORS = []
Expand Down Expand Up @@ -309,3 +307,10 @@ def _filter_empty(ls):
]
env_style_src = _filter_empty(os.environ.get("DJANGO_CSP_STYLE_SRC", "").split(","))
CSP_STYLE_SRC.extend(env_style_src)

# Configuration for requests
# https://requests.readthedocs.io/en/latest/user/advanced/#timeouts

REQUESTS_CONNECT_TIMEOUT = os.environ.get("REQUESTS_CONNECT_TIMEOUT", 3)
REQUESTS_READ_TIMEOUT = os.environ.get("REQUESTS_READ_TIMEOUT", 1)
REQUESTS_TIMEOUT = (REQUESTS_CONNECT_TIMEOUT, REQUESTS_READ_TIMEOUT)
9 changes: 0 additions & 9 deletions bin/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,6 @@ rm -f django.db

# run database migrations

if [[ ${DJANGO_LOAD_SAMPLE_DATA:-true} = false ]]; then
if [[ -d ${DJANGO_MIGRATIONS_DIR:-false} ]]; then
echo "Copying migrations from ${DJANGO_MIGRATIONS_DIR}"
cp ${DJANGO_MIGRATIONS_DIR}/0002_*.py ./benefits/core/migrations/
else
echo "DJANGO_MIGRATIONS_DIR is either unset or not a directory"
fi
fi

python manage.py migrate

# create a superuser account for backend admin access
Expand Down
14 changes: 8 additions & 6 deletions docs/configuration/README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
# Configuring the Benefits app

The [Getting Started][getting-started] section and sample configuration in the repository gives enough detail to
run the app locally. But further configuration is required before many of the integrations and features are active.
The [Getting Started][getting-started] section and sample configuration values in the repository give enough detail to
run the app locally, but further configuration is required before many of the integrations and features are active.

There are two primary components of the application configuration include:
There are two primary components of the application configuration:

- Overall app settings in [environment variables][env-vars]
- Content and more specific configurations in [sample models][data]
- Content and more specific configurations in [the data migration file][data]

The majority (but not all) of the environment variables are read into [Django settings](#django-settings) during application
Many (but not all) of the environment variables are read into [Django settings](#django-settings) during application
startup.

The sample models are also loaded into and seed Django's database at application startup time.
The model objects defined in the data migration file are also loaded into and seed Django's database at application startup time.

See the [Setting secrets](../deployment/secrets) section for how to set secret values for a deployment.

## Django settings

Expand Down
46 changes: 5 additions & 41 deletions docs/configuration/data.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
# Configuration data

!!! example "Sample data provided by data migration"
!!! example "Data migration file"

[`benefits/core/migrations/0002_sample_data.py`][data-sample]

!!! example "Helper migration file to define data migration order"

[`benefits/core/migrations/0003_data_migration_order.py`][helper-migration]

Since our initial data migration files are assumed to start with `0002` and depend only on `0001_initial`, this migration file ensures the migration graph has a defined order (which is required for the migration to run). It looks in the `benefits/core/migrations` directory for migration files starting with `0002` and declares them in its dependencies list.
[`benefits/core/migrations/0002_data.py`][data-migration]

!!! tldr "Django docs"

Expand All @@ -20,11 +14,10 @@ Django [data migrations](https://docs.djangoproject.com/en/4.0/topics/migrations

Migrations are run as the application starts up. See the [`bin/init.sh`][init] script.

The sample data provided in the repository is sufficient to run the app locally and interact with e.g. the sample Transit
The sample values provided in the repository are sufficient to run the app locally and interact with e.g. the sample Transit
Agencies.

During the [deployment](../deployment/README.md) process, an environment-specific data migration is used to build that
environment's configuration database.
During the [deployment](../deployment/README.md) process, environment-specific values are set in environment variables and are read by the data migration file to build that environment's configuration database. See the [data migration file][data-migration] for the environment variable names.

## Sample data

Expand Down Expand Up @@ -68,38 +61,9 @@ Run these commands from within the repository root, inside the devcontainer:
bin/init.sh
```

## Loading new data for different environment

Django will run all migration files found in an app's `migrations` module.

To load new data for a different environment:

1. (Optional) Set an environment variable `DJANGO_LOAD_SAMPLE_DATA` to `false` if you don't want the `core` app's sample data to be loaded.
1. Create a data migration file, and make sure the name is prefixed with `0002`. (The migration process for Benefits expects data migration files to named as such). The basic structure for the contents of this file is:
```python
from django.db import migrations


def load_data(app, *args, **kwargs):
pass


class Migration(migrations.Migration):
dependencies = [
("core", "0001_initial"),
]

operations = [
migrations.RunPython(load_data),
]
```
1. Put this file under `benefits/core/migrations`
1. If `DJANGO_LOAD_SAMPLE_DATA` is `false`, you can also set [`DJANGO_MIGRATIONS_DIR`](../environment-variables/#django_migrations_dir) to a directory path, and put your data migration there.


[core-models]: https://github.com/cal-itp/benefits/blob/dev/benefits/core/models.py
[django-load-initial-data]: https://docs.djangoproject.com/en/4.0/howto/initial-data/
[eligibility-server]: https://docs.calitp.org/eligibility-server
[data-sample]: https://github.com/cal-itp/benefits/tree/dev/benefits/core/migrations/0002_sample_data.py
[data-migration]: https://github.com/cal-itp/benefits/tree/dev/benefits/core/migrations/0002_data.py
[helper-migration]: https://github.com/cal-itp/benefits/tree/dev/benefits/core/migrations/0003_data_migration_order.py
[init]: https://github.com/cal-itp/benefits/blob/dev/bin/init.sh

0 comments on commit d48a448

Please sign in to comment.