Helsinki profile GDPR API
Django app for implementing Helsinki profile GDPR API.
This library will allow a service using Helsinki profile to implement the GDPR functionality required by open-city-profile backend.
Installation
pip install helsinki-profile-gdpr-api
Usage
-
Authentication needs to be configured for the required
django-heluser -
Model which is to be used for GDPR operations should inherit
SerializableMixinand include the requiredserialize_fieldsproperty. -
Define the following settings in your Django configuration.
Setting Example Description GDPR_API_MODEL "youths.YouthProfile" GDPR profile model in the form app_label.model_name. model_name is case-insensitive.GDPR_API_QUERY_SCOPE "jassariapi.gdprquery" API scope required for the query operation. GDPR_API_DELETE_SCOPE "jassariapi.gdprdelete" API scope required for the delete operation. -
Add the GDPR API urls into your url config:
urlpatterns = [ ... path("gdpr-api/", include("helsinki_gdpr.urls")), ]
Configurability
The configuration above is the minimum needed. With those the app uses the default behaviour. The app can also be configured in various ways if the default behaviour is not appropriate.
Setting the URL pattern
If GDPR API URLs are setup as explained in the Usage section above, the GDPR URL pattern is
gdpr-api/v1/profiles/<uuid:pk>. The first part (gdpr-api/) can be set freely in the URL config. The
rest (v1/profiles/<uuid:pk>) can be controlled with the GDPR_API_URL_PATTERN setting. It can be set to
for example users/<uuid:user_id>/gdpr. There needs to be exactly one named parameter in the URL
pattern. Its type needs to be uuid, name can be chosen freely.
Searching the model instance
By default the GDPR_API_MODEL is searched with its primary key, something like this:
from django.apps import apps
from django.conf import settings
model = apps.get_model(settings.GDPR_API_MODEL)
# The `id` is extracted from the request's URL
obj = model.objects.get(pk=id)
If pk is not the correct field lookup to use, set the setting GDPR_API_MODEL_LOOKUP to the correct
value, for example user__uuid.
If changing the field lookup that way doesn't solve the model instance searching, it's also possible to
set the GDPR_API_MODEL_LOOKUP setting to an import path to a function, for example
myapp.gdpr.get_model_instance. The function gets called whenever the GDPR API is accessed and the model
instance is needed. The function gets two arguments, the model class specified by the GDPR_API_MODEL
setting and the id from the GDPR API request's path. The function must return an instance of the model
specified by the GDPR_API_MODEL setting, if an instance is found. If no instance is found, then the
function must either return None or raise a DoesNotExist exception of the model.
Obtaining a User model instance
It's required that a User model instance can be obtained from the GDPR API model instance specified by
the GDPR_API_MODEL setting. By default the GDPR API model instance's user attribute is tried. If that
doesn't work, it's possible to configure a function that will provide the User instance. This is
achieved by setting the import path of the function to the GDPR_API_USER_PROVIDER setting, for example
myapp.gdpr.get_user. The function gets the GDPR API model instance as an argument.
Controlling how data deletion is performed
By default the GDPR delete operation deletes the GDPR_API_MODEL instance and the related User
instance. If that procedure isn't sufficient for the project, it's possible to override the data deletion
operation. This is achieved by setting the GDPR_API_DELETER setting to an import path to a function, for
example myapp.gdpr.delete_data. The function gets two arguments, the GDPR_API_MODEL instance and a
boolean value indicating if this is a dry run or not.
The function gets called within a database transaction, which gets automatically rolled back if it's a dry run operation. Thus the function is free to do database modifications even in the dry run case. All changes get rolled back afterwards. If it's not a dry run case, then the transaction is committed and all changes to the database are persisted.
If the data deletion isn't allowed, the function has two ways to indicate this:
- Return a
helsinki_gdpr.types.ErrorResponseinstance. This allows also communicating the reasons why the deletion isn't allowed. - Raise a
django.db.DatabaseErrorexception.
Development
Prerequisites
Commit message format
New commit messages must adhere to the Conventional Commits specification, and line length is limited to 72 characters.
When pre-commit is in use, commitlint
checks new commit messages for the correct format.
Code format
This project uses Ruff for code formatting and quality checking.
Basic ruff commands:
- lint:
ruff check - apply safe lint fixes:
ruff check --fix - check formatting:
ruff format --check - format:
ruff format
pre-commit can be used to install and
run all the formatting tools as git hooks automatically before a
commit.
Testing
Run the tests with:
hatch test
Test all environments in the matrix with:
hatch test -a
Available Hatch scripts
| Command | Description | Example |
|---|---|---|
hatch run test <args> |
Run pytest directly | hatch run test -k login |
hatch run lint |
Install and run pre-commit hooks | hatch run lint |
Metadata
Release files for helsinki-profile-gdpr-api 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| helsinki_profile_gdpr_api-1.1.0.tar.gz | 19.5 kB | Without provenance | Details for helsinki_profile_gdpr_api-1.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| helsinki_profile_gdpr_api-1.1.0-py3-none-any.whl | Python 3 | none | any | Details for helsinki_profile_gdpr_api-1.1.0-py3-none-any.whl |
Total release size: 28.9 kB
Release files / helsinki_profile_gdpr_api-1.1.0.tar.gz
| Download URL | helsinki_profile_gdpr_api-1.1.0.tar.gz |
|---|---|
| Size | 19.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
21388b5baaa4ea46e114137087273be12aa4de1d767601ff1854526411638257
|
|
BLAKE2b-256 checksum How to use checksums |
ac4b70307eeb427543141f87b078670a5b79b938f2b40ac197e7bb74b759df67
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / helsinki_profile_gdpr_api-1.1.0-py3-none-any.whl
| Download URL | helsinki_profile_gdpr_api-1.1.0-py3-none-any.whl |
|---|---|
| Size | 9.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8b1b80f1f8f1f2e5c2f7cf12a8084a6cee40da207a4c82caf8f655cbbc2c4d2f
|
|
BLAKE2b-256 checksum How to use checksums |
086d351c60fbce515dd2ace7a0bddf263c045d31484a4793f53304edd3a43710
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Security for helsinki-profile-gdpr-api 1.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.