diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6a24108b..602249a3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -63,7 +63,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.11", "3.12"] + python-version: ["3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 diff --git a/CHANGELOG.md b/CHANGELOG.md index a8306ef0..d2fd86db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Add login interface [#13](https://github.com/archesproject/arches-lingo/issues/13) - Add front-end router [#11](https://github.com/archesproject/arches-lingo/issues/11) +- Add concept and scheme serializers [#103](https://github.com/archesproject/arches-lingo/issues/103) - Add backend for search [#67](https://github.com/archesproject/arches-lingo/issues/67) ### Fixed diff --git a/arches_lingo/serializers.py b/arches_lingo/serializers.py new file mode 100644 index 00000000..68c7a395 --- /dev/null +++ b/arches_lingo/serializers.py @@ -0,0 +1,39 @@ +from arches.app.models.models import ResourceInstance, TileModel +from arches.app.models.serializers import ArchesModelSerializer, ArchesTileSerializer + + +class SchemeStatementSerializer(ArchesTileSerializer): + class Meta: + model = TileModel + graph_slug = "scheme" + root_node = "statement" + fields = "__all__" + + +class SchemeSerializer(ArchesModelSerializer): + # TODO: Reduce duplication with Meta.nodegroups, below? + statement = SchemeStatementSerializer(many=True, required=False) + + class Meta: + model = ResourceInstance + graph_slug = "scheme" + nodegroups = ["statement"] + fields = "__all__" + + +class ConceptStatementSerializer(ArchesTileSerializer): + class Meta: + model = TileModel + graph_slug = "concept" + root_node = "statement" + fields = "__all__" + + +class ConceptSerializer(ArchesModelSerializer): + statement = ConceptStatementSerializer(many=True, required=False) + + class Meta: + model = ResourceInstance + graph_slug = "concept" + nodegroups = ["statement"] + fields = "__all__" diff --git a/arches_lingo/settings.py b/arches_lingo/settings.py index 5337bc52..e983cbe1 100644 --- a/arches_lingo/settings.py +++ b/arches_lingo/settings.py @@ -2,10 +2,7 @@ Django settings for arches_lingo project. """ -import json import os -import sys -import arches import inspect import semantic_version from datetime import datetime, timedelta @@ -143,6 +140,7 @@ "guardian", "captcha", "revproxy", + "rest_framework", "corsheaders", "oauth2_provider", "django_celery_results", diff --git a/arches_lingo/urls.py b/arches_lingo/urls.py index 2f3df8ec..4fb28ea7 100644 --- a/arches_lingo/urls.py +++ b/arches_lingo/urls.py @@ -5,14 +5,48 @@ from arches_lingo.views.root import LingoRootView from arches_lingo.views.api.concepts import ConceptTreeView, ValueSearchView +from arches_lingo.views.api.pythonic_models import ( + ConceptDetailView, + ConceptListCreateView, + ConceptStatementDetailView, + ConceptStatementListCreateView, + SchemeDetailView, + SchemeListCreateView, + SchemeStatementDetailView, + SchemeStatementListCreateView, +) urlpatterns = [ path("", LingoRootView.as_view(), name="root"), path("login", LingoRootView.as_view(), name="login"), path("advanced-search", LingoRootView.as_view(), name="advanced-search"), path("schemes", LingoRootView.as_view(), name="schemes"), - path("api/concepts", ConceptTreeView.as_view(), name="api-concepts"), + path("api/concept-tree", ConceptTreeView.as_view(), name="api-concepts"), path("api/search", ValueSearchView.as_view(), name="api-search"), + path("api/concepts", ConceptListCreateView.as_view(), name="concepts-list-create"), + path("api/concept/", ConceptDetailView.as_view(), name="concept-detail"), + path( + "api/concept/statements", + ConceptStatementListCreateView.as_view(), + name="concept-statements-list-create", + ), + path( + "api/concept/statement/", + ConceptStatementDetailView.as_view(), + name="concept-statement-detail", + ), + path("api/schemes", SchemeListCreateView.as_view(), name="schemes-list-create"), + path("api/scheme/", SchemeDetailView.as_view(), name="scheme-detail"), + path( + "api/scheme/statements", + SchemeStatementListCreateView.as_view(), + name="scheme-statements-list-create", + ), + path( + "api/scheme/statement/", + SchemeStatementDetailView.as_view(), + name="scheme-statement-detail", + ), path("", include("arches_references.urls")), ] diff --git a/arches_lingo/views/api/pythonic_models.py b/arches_lingo/views/api/pythonic_models.py new file mode 100644 index 00000000..8daaff24 --- /dev/null +++ b/arches_lingo/views/api/pythonic_models.py @@ -0,0 +1,51 @@ +from rest_framework.permissions import IsAuthenticated +from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView + +from arches.app.views.api.mixins import ArchesModelAPIMixin + +from arches_lingo.serializers import ( + ConceptSerializer, + SchemeSerializer, + ConceptStatementSerializer, + SchemeStatementSerializer, +) + + +class SchemeListCreateView(ArchesModelAPIMixin, ListCreateAPIView): + permission_classes = [IsAuthenticated] + serializer_class = SchemeSerializer + + +class SchemeDetailView(ArchesModelAPIMixin, RetrieveUpdateDestroyAPIView): + permission_classes = [IsAuthenticated] + serializer_class = SchemeSerializer + + +class SchemeStatementListCreateView(ArchesModelAPIMixin, ListCreateAPIView): + permission_classes = [IsAuthenticated] + serializer_class = SchemeStatementSerializer + + +class SchemeStatementDetailView(ArchesModelAPIMixin, RetrieveUpdateDestroyAPIView): + permission_classes = [IsAuthenticated] + serializer_class = SchemeStatementSerializer + + +class ConceptListCreateView(ArchesModelAPIMixin, ListCreateAPIView): + permission_classes = [IsAuthenticated] + serializer_class = ConceptSerializer + + +class ConceptDetailView(ArchesModelAPIMixin, RetrieveUpdateDestroyAPIView): + permission_classes = [IsAuthenticated] + serializer_class = ConceptSerializer + + +class ConceptStatementListCreateView(ArchesModelAPIMixin, ListCreateAPIView): + permission_classes = [IsAuthenticated] + serializer_class = ConceptStatementSerializer + + +class ConceptStatementDetailView(ArchesModelAPIMixin, RetrieveUpdateDestroyAPIView): + permission_classes = [IsAuthenticated] + serializer_class = ConceptStatementSerializer diff --git a/pyproject.toml b/pyproject.toml index 76d5122c..54933b48 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,15 +16,16 @@ classifiers = [ "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Framework :: Django", "Framework :: Django :: 5.1", "Intended Audience :: Developers", "Intended Audience :: Information Technology", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", ] -requires-python = ">=3.10" +requires-python = ">=3.11" dependencies = [ - "arches @ git+https://github.com/archesproject/arches.git@dev/8.0.x", + "arches @ git+https://github.com/archesproject/arches.git@jtw/pythonic-resource-models", "arches_vue_utils @ git+https://github.com/archesproject/arches-vue-utils.git@main", "arches_references @ git+https://github.com/archesproject/arches-references.git@main", ]