From 8849c5636b69be98f6660cd59473986b8c8a953b Mon Sep 17 00:00:00 2001 From: Valentin Rigal <rigal@teklia.com> Date: Tue, 13 Oct 2020 14:57:38 +0000 Subject: [PATCH] Add a workers related workflow to the fixture --- Makefile | 2 +- arkindex/dataimport/serializers/workers.py | 2 + .../dataimport/tests/test_gitlab_provider.py | 2 +- arkindex/dataimport/tests/test_imports.py | 7 +- arkindex/dataimport/tests/test_providers.py | 2 +- arkindex/dataimport/tests/test_repos.py | 243 ++--- arkindex/dataimport/tests/test_signals.py | 4 +- arkindex/dataimport/tests/test_workerruns.py | 33 +- arkindex/dataimport/tests/test_workers.py | 99 ++- .../dataimport/tests/test_workflows_api.py | 50 +- arkindex/documents/fixtures/data.json | 840 ++++++++++-------- .../management/commands/build_fixtures.py | 49 +- .../tests/test_bulk_classification.py | 14 +- .../tests/test_bulk_element_transcriptions.py | 36 +- .../documents/tests/test_bulk_elements.py | 14 +- .../documents/tests/test_children_elements.py | 19 +- .../documents/tests/test_create_elements.py | 34 +- .../tests/test_create_transcriptions.py | 54 +- arkindex/documents/tests/test_entities_api.py | 66 +- .../documents/tests/test_list_elements.py | 23 +- arkindex/documents/tests/test_moderation.py | 54 +- .../documents/tests/test_parents_elements.py | 21 +- .../documents/tests/test_transcriptions.py | 14 +- arkindex/users/tests/test_gitlab_oauth.py | 8 +- 24 files changed, 773 insertions(+), 917 deletions(-) diff --git a/Makefile b/Makefile index 7793a20c1a..2845cddef8 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ test-fixtures: test-fixtures-run: arkindex/manage.py migrate arkindex/manage.py build_fixtures - arkindex/manage.py dumpdata --indent 4 dataimport documents images users auth > arkindex/documents/fixtures/data.json + arkindex/manage.py dumpdata --indent 4 dataimport documents images users auth ponos > arkindex/documents/fixtures/data.json test-fixtures-restore: # This first renaming ensures that arkindex_tmp_fixtures exists; we don't want to drop arkindex_dev without a backup diff --git a/arkindex/dataimport/serializers/workers.py b/arkindex/dataimport/serializers/workers.py index 8cb59b5665..9598539dca 100644 --- a/arkindex/dataimport/serializers/workers.py +++ b/arkindex/dataimport/serializers/workers.py @@ -80,6 +80,8 @@ class RepositorySerializer(serializers.ModelSerializer): type = EnumField(RepositoryType) def get_git_clone_url(self, repository): + # This check avoid to set git_clone_url when this serializer is used to list multiple + # repositories because self.instance value would be a list, even if the request user is internal if self.context['request'].user.is_internal and isinstance(self.instance, Repository) and self.instance.enabled: url = urllib.parse.urlparse(self.instance.url) return f"https://oauth2:{repository.credentials.token}@{url.netloc}{url.path}" diff --git a/arkindex/dataimport/tests/test_gitlab_provider.py b/arkindex/dataimport/tests/test_gitlab_provider.py index c6f1456cc7..0ce7da9fb8 100644 --- a/arkindex/dataimport/tests/test_gitlab_provider.py +++ b/arkindex/dataimport/tests/test_gitlab_provider.py @@ -20,7 +20,7 @@ class TestGitLabProvider(FixtureTestCase): def setUpTestData(cls): super().setUpTestData() cls.creds = cls.user.credentials.get() - cls.repo = cls.creds.repos.get() + cls.repo = cls.creds.repos.get(type=RepositoryType.IIIF) cls.rev = cls.repo.revisions.get() cls.gl_patch = patch('arkindex.dataimport.providers.Gitlab') diff --git a/arkindex/dataimport/tests/test_imports.py b/arkindex/dataimport/tests/test_imports.py index 5e6520b352..a4327feeea 100644 --- a/arkindex/dataimport/tests/test_imports.py +++ b/arkindex/dataimport/tests/test_imports.py @@ -1,7 +1,7 @@ from django.urls import reverse from rest_framework import status from arkindex_common.enums import DataImportMode -from arkindex.dataimport.models import DataImport, DataFile +from arkindex.dataimport.models import DataImport, DataFile, RepositoryType from arkindex.documents.models import Corpus, ElementType from arkindex.project.tests import FixtureAPITestCase from arkindex.users.models import User @@ -30,7 +30,7 @@ class TestImports(FixtureAPITestCase): def setUpTestData(cls): super().setUpTestData() cls.creds = cls.user.credentials.get() - cls.repo = cls.creds.repos.get() + cls.repo = cls.creds.repos.get(type=RepositoryType.IIIF) cls.rev = cls.repo.revisions.get() cls.img_df = cls.corpus.files.create( name='test.jpg', @@ -59,8 +59,7 @@ class TestImports(FixtureAPITestCase): """ workflow, created = Workflow.objects.get_or_create(id=workflow_id, defaults={'recipe': RECIPE}) if created: - # Remove tasks created from the recipe - workflow.tasks.all().delete() + # Creates the associated dataimport DataImport.objects.create(workflow=workflow, mode=DataImportMode.Workers, creator=self.user) return Task.objects.create(run=run, depth=depth, workflow=workflow, state=state, slug=str(uuid.uuid4())) diff --git a/arkindex/dataimport/tests/test_providers.py b/arkindex/dataimport/tests/test_providers.py index a77162ebe0..e67d56fbff 100644 --- a/arkindex/dataimport/tests/test_providers.py +++ b/arkindex/dataimport/tests/test_providers.py @@ -12,7 +12,7 @@ class TestProviders(FixtureAPITestCase): def setUpTestData(cls): super().setUpTestData() cls.creds = cls.user.credentials.get() - cls.repo = cls.creds.repos.get() + cls.repo = cls.creds.repos.get(type=RepositoryType.IIIF) cls.rev = cls.repo.revisions.get() def test_init(self): diff --git a/arkindex/dataimport/tests/test_repos.py b/arkindex/dataimport/tests/test_repos.py index 914feb0659..282d4c5511 100644 --- a/arkindex/dataimport/tests/test_repos.py +++ b/arkindex/dataimport/tests/test_repos.py @@ -5,8 +5,7 @@ from rest_framework.serializers import DateTimeField from ponos.models import Workflow, State from arkindex_common.enums import DataImportMode from arkindex.project.tests import FixtureTestCase -from arkindex_common.ml_tool import MLToolType -from arkindex.dataimport.models import Repository, RepositoryType, DataImport, Worker, WorkerVersion, WorkerVersionState +from arkindex.dataimport.models import Repository, RepositoryType, DataImport, WorkerVersion, WorkerVersionState from arkindex.users.models import User from mock import patch, MagicMock @@ -14,10 +13,6 @@ RECIPE = ''' tasks: first: image: alpine - second: - parents: - - first - image: hello-world ''' @@ -26,11 +21,12 @@ class TestRepositories(FixtureTestCase): def setUp(self): super().setUp() self.creds = self.user.credentials.get() - self.repo = self.creds.repos.get() - self.rev = self.repo.revisions.get() + self.iiif_repo = self.creds.repos.get(type=RepositoryType.IIIF) + self.worker_repo = self.creds.repos.get(type=RepositoryType.Worker) + self.rev = self.iiif_repo.revisions.get() self.serialized_revision = { 'id': str(self.rev.id), - 'repo_id': str(self.repo.id), + 'repo_id': str(self.iiif_repo.id), 'author': self.rev.author, 'commit_url': self.rev.commit_url, 'date': DateTimeField().to_representation(value=self.rev.created), @@ -38,22 +34,50 @@ class TestRepositories(FixtureTestCase): 'message': self.rev.message } + def build_repository_response(self): + return [ + { + 'id': str(self.iiif_repo.id), + 'type': RepositoryType.IIIF.value, + 'corpora': [str(c.id) for c in self.iiif_repo.corpora.all()], + 'enabled': True, + 'git_clone_url': None, + 'url': self.iiif_repo.url, + 'workers': [], + }, { + 'id': str(self.worker_repo.id), + 'type': RepositoryType.Worker.value, + 'corpora': [str(c.id) for c in self.worker_repo.corpora.all()], + 'enabled': True, + 'git_clone_url': None, + 'url': self.worker_repo.url, + 'workers': [ + { + 'id': str(w.id), + 'name': w.name, + 'type': w.type.value, + 'slug': w.slug + } for w in self.worker_repo.workers.all() + ] + } + ] + def test_delete_credentials_null(self): """ Check deleting OAuthCredentials do not delete repositories and revisions """ self.creds.delete() self.assertTrue(Repository.objects.filter(url='http://gitlab/repo').exists()) - self.repo.refresh_from_db() - self.assertTrue(self.repo.revisions.exists()) + self.iiif_repo.refresh_from_db() + self.assertTrue(self.iiif_repo.revisions.exists()) def test_no_credentials_no_import(self): """ Check Repository imports do not start without credentials """ - self.repo.credentials = None - self.repo.save() - self.assertEqual(Workflow.objects.count(), 0) + self.iiif_repo.credentials = None + self.iiif_repo.save() + workflows_count = Workflow.objects.count() di = DataImport.objects.create( mode=DataImportMode.Repository, @@ -68,99 +92,51 @@ class TestRepositories(FixtureTestCase): with self.assertRaises(ValidationError): di.retry() - self.assertEqual(Workflow.objects.count(), 0) + self.assertEqual(Workflow.objects.count(), workflows_count) def test_list_repository_requires_login(self): with self.assertNumQueries(0): response = self.client.get(reverse('api:repository-list')) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - def test_list_repository_with_workers(self): - worker = Worker.objects.create( - name="my worker", - slug="my_worker", - type=MLToolType.Classifier, - repository=self.repo - ) - self.client.force_login(self.user) - with self.assertNumQueries(6): - response = self.client.get(reverse('api:repository-list')) - self.assertEqual(response.status_code, status.HTTP_200_OK) - data = response.json() - self.assertEqual(len(data['results']), 1) - self.assertDictEqual(data['results'][0], { - 'id': str(self.repo.id), - 'type': RepositoryType.IIIF.value, - 'corpora': [str(c.id) for c in self.repo.corpora.all()], - 'enabled': True, - 'git_clone_url': None, - 'url': self.repo.url, - 'workers': [{ - 'id': str(worker.id), - 'name': worker.name, - 'slug': worker.slug, - 'type': worker.type.value, - }], - }) - def test_list_repository_external_user(self): self.client.force_login(self.user) with self.assertNumQueries(6): response = self.client.get(reverse('api:repository-list')) self.assertEqual(response.status_code, status.HTTP_200_OK) data = response.json() - self.assertEqual(len(data['results']), 1) - self.assertDictEqual(data['results'][0], { - 'id': str(self.repo.id), - 'type': RepositoryType.IIIF.value, - 'corpora': [str(c.id) for c in self.repo.corpora.all()], - 'enabled': True, - 'git_clone_url': None, - 'url': self.repo.url, - 'workers': [], - }) + self.assertEqual(len(data['results']), 2) + self.assertCountEqual(data['results'], self.build_repository_response()) def test_list_repository_internal_user(self): + """ + Multiple repository serialization should not include the git_clone_url field + """ self.client.force_login(self.internal_user) with self.assertNumQueries(6): response = self.client.get(reverse('api:repository-list')) self.assertEqual(response.status_code, status.HTTP_200_OK) data = response.json() - self.assertEqual(len(data['results']), 1) - self.assertDictEqual(data['results'][0], { - 'id': str(self.repo.id), - 'type': RepositoryType.IIIF.value, - 'corpora': [str(c.id) for c in self.repo.corpora.all()], - 'enabled': True, - 'git_clone_url': None, - 'url': self.repo.url, - 'workers': [], - }) + self.assertEqual(len(data['results']), 2) + self.maxDiff = None + self.assertCountEqual(data['results'], self.build_repository_response()) def test_list_repository_multiple_refs(self): """ Listed repositories should not be duplicated """ - self.repo.corpora.create() + self.iiif_repo.corpora.create() self.client.force_login(self.internal_user) with self.assertNumQueries(6): response = self.client.get(reverse('api:repository-list')) self.assertEqual(response.status_code, status.HTTP_200_OK) data = response.json() - self.assertEqual(len(data['results']), 1) - self.assertDictEqual(data['results'][0], { - 'id': str(self.repo.id), - 'type': RepositoryType.IIIF.value, - 'corpora': [str(c.id) for c in self.repo.corpora.all()], - 'enabled': True, - 'git_clone_url': None, - 'url': self.repo.url, - 'workers': [], - }) + self.assertEqual(len(data['results']), 2) + self.assertCountEqual(data['results'], self.build_repository_response()) def test_repository_retrieve_requires_login(self): response = self.client.get( - reverse('api:repository-retrieve', kwargs={'pk': str(self.repo.id)}) + reverse('api:repository-retrieve', kwargs={'pk': str(self.iiif_repo.id)}) ) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) @@ -176,56 +152,56 @@ class TestRepositories(FixtureTestCase): self.client.force_login(self.user) self.assertFalse(self.user.is_internal) response = self.client.get( - reverse('api:repository-retrieve', kwargs={'pk': str(self.repo.id)}) + reverse('api:repository-retrieve', kwargs={'pk': str(self.iiif_repo.id)}) ) self.assertEqual(response.status_code, status.HTTP_200_OK) data = response.json() self.assertDictEqual(data, { - 'id': str(self.repo.id), + 'id': str(self.iiif_repo.id), 'type': RepositoryType.IIIF.value, - 'corpora': [str(c.id) for c in self.repo.corpora.all()], + 'corpora': [str(c.id) for c in self.iiif_repo.corpora.all()], 'enabled': True, 'git_clone_url': None, - 'url': self.repo.url, + 'url': self.iiif_repo.url, 'workers': [], }) def test_repository_retrieve_internal_user(self): self.client.force_login(self.internal_user) response = self.client.get( - reverse('api:repository-retrieve', kwargs={'pk': str(self.repo.id)}) + reverse('api:repository-retrieve', kwargs={'pk': str(self.iiif_repo.id)}) ) self.assertEqual(response.status_code, status.HTTP_200_OK) data = response.json() self.assertDictEqual(data, { - 'id': str(self.repo.id), + 'id': str(self.iiif_repo.id), 'type': RepositoryType.IIIF.value, - 'corpora': [str(c.id) for c in self.repo.corpora.all()], + 'corpora': [str(c.id) for c in self.iiif_repo.corpora.all()], 'enabled': True, 'git_clone_url': 'https://oauth2:oauth-token@gitlab/repo', - 'url': self.repo.url, + 'url': self.iiif_repo.url, 'workers': [], }) def test_repository_retrieve_disabled_repo(self): - self.repo.credentials = None - self.repo.save() + self.iiif_repo.credentials = None + self.iiif_repo.save() internal_user = User.objects.create_user('internal@test.com', internal=True) internal_user.verified_email = True internal_user.save() self.client.force_login(internal_user) self.assertFalse(self.user.is_internal) with self.assertNumQueries(5): - response = self.client.get(reverse('api:repository-retrieve', kwargs={'pk': str(self.repo.id)})) + response = self.client.get(reverse('api:repository-retrieve', kwargs={'pk': str(self.iiif_repo.id)})) self.assertEqual(response.status_code, status.HTTP_200_OK) data = response.json() self.assertDictEqual(data, { - 'id': str(self.repo.id), + 'id': str(self.iiif_repo.id), 'type': RepositoryType.IIIF.value, - 'corpora': [str(c.id) for c in self.repo.corpora.all()], + 'corpora': [str(c.id) for c in self.iiif_repo.corpora.all()], 'enabled': False, 'git_clone_url': None, - 'url': self.repo.url, + 'url': self.iiif_repo.url, 'workers': [], }) @@ -247,11 +223,11 @@ class TestRepositories(FixtureTestCase): self.client.force_login(self.user) right = self.corpus.corpus_right.get(user=self.user) self.assertTrue(right.can_write) - self.assertTrue(self.repo.credentials.user, self.user) + self.assertTrue(self.iiif_repo.credentials.user, self.user) for i in range(3): # Add corpora depending on the same repository - self.repo.corpora.create() - response = self.client.delete(reverse('api:repository-retrieve', kwargs={'pk': str(self.repo.id)})) + self.iiif_repo.corpora.create() + response = self.client.delete(reverse('api:repository-retrieve', kwargs={'pk': str(self.iiif_repo.id)})) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_repository_delete_creator_write_access(self): @@ -261,17 +237,17 @@ class TestRepositories(FixtureTestCase): self.client.force_login(self.user) right = self.corpus.corpus_right.get(user=self.user) self.assertTrue(right.can_write) - self.assertTrue(self.repo.credentials.user, self.user) + self.assertTrue(self.iiif_repo.credentials.user, self.user) corpora = [self.corpus] for i in range(3): # Add corpora depending on the same repository with write acces for this user - corpus = self.repo.corpora.create(name=str(i)) + corpus = self.iiif_repo.corpora.create(name=str(i)) corpus.corpus_right.create(user=self.user, can_write=True) corpora.append(corpus) - response = self.client.delete(reverse('api:repository-retrieve', kwargs={'pk': str(self.repo.id)})) + response = self.client.delete(reverse('api:repository-retrieve', kwargs={'pk': str(self.iiif_repo.id)})) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) with self.assertRaises(Repository.DoesNotExist): - self.repo.refresh_from_db() + self.iiif_repo.refresh_from_db() for corpus in corpora: corpus.refresh_from_db() self.assertIsNone(corpus.repository) @@ -300,70 +276,39 @@ class TestRepositories(FixtureTestCase): self.assertDictEqual(data, self.serialized_revision) def test_revision_state(self): - # No version on the revision --> Revision : Created - self.assertEqual(self.rev.state, WorkerVersionState.Created) + revision = self.worker_repo.revisions.create() - worker_1 = Worker.objects.create( - repository=self.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - worker_2 = Worker.objects.create( - repository=self.repo, - name='Worker 2', - slug='worker_2', - type=MLToolType.Classifier - ) - version_1 = WorkerVersion.objects.create( - worker=worker_1, - revision=self.rev, - configuration={"test": "test1"} - ) - version_2 = WorkerVersion.objects.create( - worker=worker_2, - revision=self.rev, - configuration={"test": "test1"} - ) + # No version on the revision --> Revision : Created + self.assertEqual(revision.state, WorkerVersionState.Created) - workflow = Workflow.objects.create(recipe=RECIPE) - workflow.start() - task_1, task_2 = workflow.tasks.order_by('slug') - artifact_1 = task_1.artifacts.create( - path='path/to/file.tar.zst', - size=100, - content_type='application/x-tar+zstd', + WorkerVersion.objects.filter(worker__repository=self.worker_repo).update( + revision=revision, + state=WorkerVersionState.Created ) - artifact_2 = task_2.artifacts.create( - path='path/to/file.tar.zst', - size=100, - content_type='application/x-tar+zstd', - ) - + versions = list(revision.versions.all()) # Version 1 : Created | Version 2 : Created --> Revision : Created - self.assertEqual(self.rev.state, WorkerVersionState.Created) + self.assertEqual(WorkerVersion.objects.filter(worker__repository=self.worker_repo).first().state, WorkerVersionState.Created) + self.assertEqual(revision.state, WorkerVersionState.Created) - version_1.state = WorkerVersionState.Error - version_1.save() + versions[0].state = WorkerVersionState.Error + versions[0].save() # Version 1 : Error | Version 2 : Created --> Revision : Error - self.assertEqual(self.rev.state, WorkerVersionState.Error) + self.assertEqual(revision.state, WorkerVersionState.Error) - version_1.state = WorkerVersionState.Processing - version_1.save() + versions[0].state = WorkerVersionState.Processing + versions[0].save() # Version 1 : Processing | Version 2 : Created --> Revision : Processing - self.assertEqual(self.rev.state, WorkerVersionState.Processing) + self.assertEqual(revision.state, WorkerVersionState.Processing) - version_1.state = WorkerVersionState.Available - version_1.docker_image = artifact_1 - version_1.save() + versions[0].state = WorkerVersionState.Available + versions[0].save() # Version 1 : Available | Version 2 : Created --> Revision : Created - self.assertEqual(self.rev.state, WorkerVersionState.Created) + self.assertEqual(revision.state, WorkerVersionState.Created) - version_2.state = WorkerVersionState.Available - version_2.docker_image = artifact_2 - version_2.save() + versions[1].state = WorkerVersionState.Available + versions[1].save() # Version 1 : Available | Version 2 : Available --> Revision : Available - self.assertEqual(self.rev.state, WorkerVersionState.Available) + self.assertEqual(revision.state, WorkerVersionState.Available) @patch('arkindex.users.models.OAuthCredentials.git_provider_class') def test_list_repositories(self, git_provider_mock): @@ -442,7 +387,7 @@ class TestRepositories(FixtureTestCase): """ self.client.force_login(self.user) git_provider_mock().get_or_create_revision.return_value = self.rev, None - git_provider_mock().create_repo.return_value = self.repo + git_provider_mock().create_repo.return_value = self.iiif_repo with self.assertNumQueries(11): response = self.client.post(reverse('api:available-repositories', kwargs={'pk': self.creds.id}), {'id': 1111}) self.assertEqual(response.status_code, status.HTTP_201_CREATED) diff --git a/arkindex/dataimport/tests/test_signals.py b/arkindex/dataimport/tests/test_signals.py index 231300c1d8..783bc27d88 100644 --- a/arkindex/dataimport/tests/test_signals.py +++ b/arkindex/dataimport/tests/test_signals.py @@ -1,6 +1,6 @@ from arkindex_common.ml_tool import MLToolType from arkindex_common.enums import DataImportMode -from arkindex.dataimport.models import Worker, WorkerVersion, WorkerRun +from arkindex.dataimport.models import Worker, WorkerVersion, WorkerRun, RepositoryType from arkindex.dataimport.signals import _list_ancestors from arkindex.project.tests import FixtureAPITestCase from rest_framework.exceptions import ValidationError @@ -15,7 +15,7 @@ class TestSignals(FixtureAPITestCase): def setUpTestData(cls): super().setUpTestData() cls.creds = cls.user.credentials.get() - cls.repo = cls.creds.repos.get() + cls.repo = cls.creds.repos.get(type=RepositoryType.IIIF) cls.rev_1 = cls.repo.revisions.get() cls.rev_2 = cls.repo.revisions.create( hash='2', diff --git a/arkindex/dataimport/tests/test_workerruns.py b/arkindex/dataimport/tests/test_workerruns.py index 85cfa2a519..347e0eb84c 100644 --- a/arkindex/dataimport/tests/test_workerruns.py +++ b/arkindex/dataimport/tests/test_workerruns.py @@ -1,9 +1,8 @@ from unittest.mock import patch from django.urls import reverse from rest_framework import status -from arkindex_common.ml_tool import MLToolType from arkindex_common.enums import DataImportMode -from arkindex.dataimport.models import Worker, WorkerVersion, WorkerRun +from arkindex.dataimport.models import WorkerVersion, WorkerRun from ponos.models import Workflow from arkindex.project.tests import FixtureAPITestCase import uuid @@ -27,27 +26,11 @@ class TestWorkerRuns(FixtureAPITestCase): @classmethod def setUpTestData(cls): super().setUpTestData() - cls.creds = cls.user.credentials.get() - cls.repo = cls.creds.repos.get() - cls.rev = cls.repo.revisions.get() - - cls.worker_1 = Worker.objects.create( - repository=cls.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - cls.version_1 = WorkerVersion.objects.create( - worker=cls.worker_1, - revision=cls.rev, - configuration={"test": "test1"} - ) - cls.dataimport_1 = cls.corpus.imports.create(creator=cls.user, mode=DataImportMode.Workers) - cls.run_1 = cls.dataimport_1.worker_runs.create( - version=cls.version_1, - parents=[], - ) + cls.version_1 = WorkerVersion.objects.get(worker__slug='reco') + cls.worker_1 = cls.version_1.worker + cls.repo = cls.worker_1.repository + cls.run_1 = cls.dataimport_1.worker_runs.create(version=cls.version_1, parents=[]) cls.dataimport_2 = cls.corpus.imports.create(creator=cls.user, mode=DataImportMode.Workers) def test_runs_list_requires_login(self): @@ -394,7 +377,7 @@ class TestWorkerRuns(FixtureAPITestCase): @patch('arkindex.dataimport.models.WorkerVersion.docker_image', ArtifactMock(artifact_id)) def test_build_task_recipe_no_parent(self): self.assertDictEqual(self.run_1.build_task_recipe('import', '/data/import/elements.json'), { - 'image': f'gitlab/repo/worker_1:{str(self.version_1.id)}', + 'image': f'my_repo.fake/workers/worker/reco:{str(self.version_1.id)}', 'command': None, 'artifact': str(self.artifact_id), 'parents': ['import'], @@ -419,9 +402,9 @@ class TestWorkerRuns(FixtureAPITestCase): ) self.assertDictEqual(run_2.build_task_recipe('import', '/data/import/elements.json'), { - 'image': f'gitlab/repo/worker_1:{str(version_2.id)}', + 'image': f'my_repo.fake/workers/worker/reco:{str(version_2.id)}', 'command': None, 'artifact': str(self.artifact_id), - 'parents': [f'worker_1_{str(self.version_1.id)[0:6]}'], + 'parents': [f'reco_{str(self.version_1.id)[0:6]}'], 'env': {'TASK_ELEMENTS': '/data/import/elements.json', 'WORKER_VERSION_ID': str(version_2.id)}, }) diff --git a/arkindex/dataimport/tests/test_workers.py b/arkindex/dataimport/tests/test_workers.py index 9ec307e250..f0101cc058 100644 --- a/arkindex/dataimport/tests/test_workers.py +++ b/arkindex/dataimport/tests/test_workers.py @@ -25,15 +25,11 @@ class TestWorkersWorkerVersions(FixtureAPITestCase): def setUpTestData(cls): super().setUpTestData() cls.creds = cls.user.credentials.get() - cls.repo = cls.creds.repos.get() + cls.repo = cls.creds.repos.get(type=RepositoryType.Worker) cls.rev = cls.repo.revisions.get() - cls.worker_1 = Worker.objects.create( - repository=cls.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) + cls.worker_1 = Worker.objects.get(slug='reco') + cls.worker_2 = Worker.objects.get(slug='dla') cls.rev2 = Revision.objects.create( hash='1234', message='commit message', @@ -42,11 +38,7 @@ class TestWorkersWorkerVersions(FixtureAPITestCase): ) def setUp(self): - self.version_1 = WorkerVersion.objects.create( - worker=self.worker_1, - revision=self.rev, - configuration={"test": "test1"} - ) + self.version_1 = WorkerVersion.objects.get(worker=self.worker_1) # Tests on get_query_set for WorkerList def test_workers_list_requires_login(self): @@ -58,12 +50,20 @@ class TestWorkersWorkerVersions(FixtureAPITestCase): response = self.client.get(reverse('api:repository-workers', kwargs={'pk': str(self.repo.id)})) self.assertEqual(response.status_code, status.HTTP_200_OK) data = response.json() - self.assertEqual(len(data), 1) - worker = data[0] - self.assertEqual(worker['id'], str(self.worker_1.id)) - self.assertEqual(worker['name'], 'Worker 1') - self.assertEqual(worker['slug'], 'worker_1') - self.assertEqual(worker['type'], MLToolType.Classifier.value) + self.assertEqual(len(data), 2) + self.assertCountEqual(data, [ + { + 'id': str(self.worker_1.id), + 'name': 'Recognizer', + 'slug': 'reco', + 'type': 'recognizer' + }, { + 'id': str(self.worker_2.id), + 'name': 'Document layout analyser', + 'slug': 'dla', + 'type': 'dla' + } + ]) def test_workers_list_filter_repository(self): self.client.force_login(self.user) @@ -139,14 +139,14 @@ class TestWorkersWorkerVersions(FixtureAPITestCase): # A worker named Worker 1 already exists with the same slug on this repo response = self.client.post( reverse('api:repository-workers', kwargs={'pk': str(self.repo.id)}), - data={'name': 'Worker Test', 'slug': 'worker_1', 'type': 'classifier'} + data={'name': 'Worker Test', 'slug': 'reco', 'type': 'classifier'} ) self.assertEqual(response.status_code, status.HTTP_200_OK) data = response.json() self.assertEqual(data['id'], str(self.worker_1.id)) - self.assertEqual(data['name'], 'Worker 1') - self.assertEqual(data['slug'], 'worker_1') - self.assertEqual(data['type'], MLToolType.Classifier.value) + self.assertEqual(data['name'], 'Recognizer') + self.assertEqual(data['slug'], 'reco') + self.assertEqual(data['type'], MLToolType.Recognizer.value) def test_workers_post_empty(self): self.client.force_login(self.user) @@ -173,7 +173,7 @@ class TestWorkersWorkerVersions(FixtureAPITestCase): self.assertEqual(len(data), 1) version = data[0] self.assertEqual(version['id'], str(self.version_1.id)) - self.assertEqual(version['configuration'], {"test": "test1"}) + self.assertEqual(version['configuration'], {"test": 42}) self.assertEqual(version['revision']['id'], str(self.rev.id)) def test_versions_list_filter_worker(self): @@ -255,9 +255,9 @@ class TestWorkersWorkerVersions(FixtureAPITestCase): self.assertEqual(response.status_code, status.HTTP_200_OK) data = response.json() self.assertEqual(data['id'], str(self.version_1.id)) - self.assertEqual(data['configuration'], {"test": "test1"}) + self.assertEqual(data['configuration'], {"test": 42}) self.assertEqual(data['revision']['id'], str(self.rev.id)) - self.assertEqual(data['state'], 'created') + self.assertEqual(data['state'], 'available') def test_versions_post_empty(self): self.client.force_login(self.user) @@ -290,13 +290,14 @@ class TestWorkersWorkerVersions(FixtureAPITestCase): self.assertEqual(revision['id'], str(self.rev.id)) worker = data.pop('worker') self.assertEqual(worker['id'], str(self.worker_1.id)) + self.maxDiff = None self.assertDictEqual(data, { 'id': str(self.version_1.id), - 'configuration': {"test": "test1"}, - 'docker_image': None, + 'configuration': {"test": 42}, + 'docker_image': str(self.version_1.docker_image.id), 'docker_image_iid': None, - 'docker_image_name': f'gitlab/repo/worker_1:{self.version_1.id}', - 'state': 'created', + 'docker_image_name': f'my_repo.fake/workers/worker/reco:{self.version_1.id}', + 'state': 'available', }) def test_update_version_requires_login(self): @@ -322,37 +323,37 @@ class TestWorkersWorkerVersions(FixtureAPITestCase): ) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_update_version(self): - self.assertEqual(self.version_1.docker_image, None) - - workflow = Workflow.objects.create(recipe=RECIPE) - workflow.start() - task = workflow.tasks.get(slug='first') - artifact = task.artifacts.create( - path='path/to/file.json', - size=100, - content_type='application/json', - ) + def test_update_worker_version(self): + """ + Update worker version artifact, configuration and state + """ + docker_image = self.version_1.docker_image + self.version_1.state = WorkerVersionState.Created + self.version_1.docker_image = None + self.version_1.save() self.client.force_login(self.user) response = self.client.patch( reverse('api:version-retrieve', kwargs={'pk': str(self.version_1.id)}), data={ 'configuration': {"test": "test2"}, - 'docker_image': str(artifact.id), + 'docker_image': str(docker_image.id), 'state': 'error' }, format='json' ) self.assertEqual(response.status_code, status.HTTP_200_OK) data = response.json() self.assertEqual(data['id'], str(self.version_1.id)) + self.version_1.refresh_from_db() self.assertEqual(data['configuration'], {"test": "test2"}) - self.assertEqual(data['docker_image'], str(artifact.id)) + self.assertEqual(data['docker_image'], str(docker_image.id)) self.assertIsNone(data['docker_image_iid']) self.assertEqual(data['state'], 'error') def test_update_version_valid(self): - self.assertEqual(self.version_1.docker_image, None) + self.version_1.state = WorkerVersionState.Created + self.version_1.docker_image = None + self.version_1.save() workflow = Workflow.objects.create(recipe=RECIPE) workflow.start() @@ -382,7 +383,9 @@ class TestWorkersWorkerVersions(FixtureAPITestCase): self.assertEqual(data['state'], 'available') def test_update_version_available_requires_docker_image(self): - self.assertEqual(self.version_1.docker_image, None) + self.version_1.state = WorkerVersionState.Created + self.version_1.docker_image = None + self.version_1.save() self.client.force_login(self.user) response = self.client.patch( @@ -449,7 +452,7 @@ class TestWorkersWorkerVersions(FixtureAPITestCase): }) def test_property_docker_image_name(self): - self.assertEqual(self.version_1.docker_image_name, f'gitlab/repo/worker_1:{self.version_1.id}') + self.assertEqual(self.version_1.docker_image_name, f'my_repo.fake/workers/worker/reco:{self.version_1.id}') def test_property_docker_image_name_explicit(self): version_2 = WorkerVersion.objects.create( @@ -460,11 +463,11 @@ class TestWorkersWorkerVersions(FixtureAPITestCase): ) self.assertEqual( version_2.docker_image_name, - 'gitlab/repo/worker_1:12341234-1234-1234-1234-123412341234' + 'my_repo.fake/workers/worker/reco:12341234-1234-1234-1234-123412341234' ) def test_property_slug(self): - self.assertEqual(self.version_1.slug, f'worker_1_{str(self.version_1.id)[0:6]}') + self.assertEqual(self.version_1.slug, f'reco_{str(self.version_1.id)[0:6]}') def test_property_slug_explicit(self): version_2 = WorkerVersion.objects.create( @@ -473,7 +476,7 @@ class TestWorkersWorkerVersions(FixtureAPITestCase): revision=self.rev2, configuration={"test": "test1"} ) - self.assertEqual(version_2.slug, 'worker_1_012345') + self.assertEqual(version_2.slug, 'reco_012345') def test_property_docker_command_empty(self): self.assertEqual(self.version_1.docker_command, None) diff --git a/arkindex/dataimport/tests/test_workflows_api.py b/arkindex/dataimport/tests/test_workflows_api.py index 5266901032..21c864446c 100644 --- a/arkindex/dataimport/tests/test_workflows_api.py +++ b/arkindex/dataimport/tests/test_workflows_api.py @@ -1,10 +1,9 @@ from django.test import override_settings from rest_framework.reverse import reverse from rest_framework import status -from arkindex_common.ml_tool import MLToolType from arkindex_common.enums import DataImportMode from ponos.models import State, Workflow -from arkindex.dataimport.models import DataImport, Worker, WorkerVersion +from arkindex.dataimport.models import DataImport, WorkerVersion, RepositoryType from arkindex.documents.models import Element, Corpus from arkindex.project.tests import FixtureAPITestCase import yaml @@ -34,29 +33,17 @@ class TestWorkflows(FixtureAPITestCase): # Workers DataImportMode cls.creds = cls.user.credentials.get() - cls.repo = cls.creds.repos.get() + cls.repo = cls.creds.repos.get(type=RepositoryType.Worker) cls.rev_1 = cls.repo.revisions.get() cls.rev_2 = cls.repo.revisions.create( hash='2', message='commit message', author='bob', ) - cls.worker_1 = Worker.objects.create( - repository=cls.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - cls.version_1 = WorkerVersion.objects.create( - worker=cls.worker_1, - revision=cls.rev_1, - configuration={"test": "test1"} - ) - cls.version_2 = WorkerVersion.objects.create( - worker=cls.worker_1, - revision=cls.rev_2, - configuration={"test": "test2"} - ) + cls.version_1 = WorkerVersion.objects.get(worker__slug='reco') + cls.worker_1 = cls.version_1.worker + cls.version_2 = WorkerVersion.objects.get(worker__slug='dla') + cls.worker_2 = cls.version_2.worker @override_settings( ARKINDEX_TASKS_IMAGE='tasks:latest', @@ -448,16 +435,6 @@ class TestWorkflows(FixtureAPITestCase): workflow_tmp = Workflow.objects.create(recipe=RECIPE) workflow_tmp.start() - task_tmp = workflow_tmp.tasks.get(slug='first') - artifact = task_tmp.artifacts.create( - path='path/to/file.json', - size=100, - content_type='application/json', - ) - self.version_1.docker_image = artifact - self.version_1.save() - self.version_2.docker_image = artifact - self.version_2.save() self.assertIsNone(dataimport_2.workflow) @@ -470,6 +447,7 @@ class TestWorkflows(FixtureAPITestCase): dataimport_2.refresh_from_db() self.assertEqual(dataimport_2.state, State.Unscheduled) self.assertIsNotNone(dataimport_2.workflow) + self.maxDiff = None self.assertDictEqual(yaml.safe_load(dataimport_2.workflow.recipe)['tasks'], { 'import': { @@ -477,20 +455,20 @@ class TestWorkflows(FixtureAPITestCase): f'{dataimport_2.id} --chunks-number 1', 'image': 'registry.gitlab.com/arkindex/tasks' }, - f'worker_1_{str(self.version_1.id)[0:6]}': + f'reco_{str(self.version_1.id)[0:6]}': { 'command': None, - 'image': f'gitlab/repo/worker_1:{self.version_1.id}', - 'artifact': str(artifact.id), + 'image': f'my_repo.fake/workers/worker/reco:{self.version_1.id}', + 'artifact': str(self.version_1.docker_image.id), 'parents': ['import'], 'env': {'TASK_ELEMENTS': '/data/import/elements.json', 'WORKER_VERSION_ID': str(self.version_1.id)} }, - f'worker_1_{str(self.version_2.id)[0:6]}': + f'dla_{str(self.version_2.id)[0:6]}': { 'command': None, - 'image': f'gitlab/repo/worker_1:{self.version_2.id}', - 'artifact': str(artifact.id), - 'parents': [f'worker_1_{str(self.version_1.id)[0:6]}'], + 'image': f'my_repo.fake/workers/worker/dla:{self.version_2.id}', + 'artifact': str(self.version_1.docker_image.id), + 'parents': [f'reco_{str(self.version_1.id)[0:6]}'], 'env': {'TASK_ELEMENTS': '/data/import/elements.json', 'WORKER_VERSION_ID': str(self.version_2.id)} } }) diff --git a/arkindex/documents/fixtures/data.json b/arkindex/documents/fixtures/data.json index 60ce2a6e0f..0cdc384ccf 100644 --- a/arkindex/documents/fixtures/data.json +++ b/arkindex/documents/fixtures/data.json @@ -1,44 +1,115 @@ [ { "model": "dataimport.repository", - "pk": "71ea33be-c05f-4813-9222-0d66e4342e71", + "pk": "d0cd8a85-8f30-43e1-ba19-7bd0dacb2041", "fields": { "url": "http://gitlab/repo", "type": "iiif", "hook_token": "hook-token", - "credentials": "fdd4c059-6d10-4aaa-8308-a0aa4bf20284", + "credentials": "d21e40e2-32d2-4903-ac4a-6672dc6c14ba", + "provider_name": "GitLabProvider" + } +}, +{ + "model": "dataimport.repository", + "pk": "f020dbad-f6ba-4d95-9bba-35dc80272943", + "fields": { + "url": "http://my_repo.fake/workers/worker", + "type": "worker", + "hook_token": "worker-hook-token", + "credentials": "d21e40e2-32d2-4903-ac4a-6672dc6c14ba", "provider_name": "GitLabProvider" } }, { "model": "dataimport.revision", - "pk": "0ab63e11-590a-49b9-8e62-4c867ab68e02", + "pk": "3ddfb063-eff0-4a9a-8b0f-000c0eca0f7a", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "repo": "71ea33be-c05f-4813-9222-0d66e4342e71", + "repo": "d0cd8a85-8f30-43e1-ba19-7bd0dacb2041", "hash": "42", "message": "a", "author": "me" } }, +{ + "model": "dataimport.revision", + "pk": "796847cd-9463-4496-a102-c1a5f825e50d", + "fields": { + "created": "2020-02-02T01:23:45.678Z", + "updated": "2020-02-02T01:23:45.678Z", + "repo": "f020dbad-f6ba-4d95-9bba-35dc80272943", + "hash": "1337", + "message": "My w0rk3r", + "author": "Test user" + } +}, +{ + "model": "dataimport.worker", + "pk": "29a773f3-d140-48e3-b1e4-29325f9dbc6f", + "fields": { + "name": "Recognizer", + "slug": "reco", + "type": "recognizer", + "repository": "f020dbad-f6ba-4d95-9bba-35dc80272943" + } +}, +{ + "model": "dataimport.worker", + "pk": "cf4243ca-5f42-4dbd-a2fe-14a8e75a33d8", + "fields": { + "name": "Document layout analyser", + "slug": "dla", + "type": "dla", + "repository": "f020dbad-f6ba-4d95-9bba-35dc80272943" + } +}, +{ + "model": "dataimport.workerversion", + "pk": "8d2ca1e7-f4f9-4403-8569-20e9712a897a", + "fields": { + "worker": "29a773f3-d140-48e3-b1e4-29325f9dbc6f", + "revision": "796847cd-9463-4496-a102-c1a5f825e50d", + "configuration": { + "test": 42 + }, + "state": "available", + "docker_image": "71a4b60b-a2f2-4503-8f5d-9d3c38f66626", + "docker_image_iid": null + } +}, +{ + "model": "dataimport.workerversion", + "pk": "afa4a177-b8d2-4bcf-aaa7-b00196807e1d", + "fields": { + "worker": "cf4243ca-5f42-4dbd-a2fe-14a8e75a33d8", + "revision": "796847cd-9463-4496-a102-c1a5f825e50d", + "configuration": { + "test": 42 + }, + "state": "available", + "docker_image": "71a4b60b-a2f2-4503-8f5d-9d3c38f66626", + "docker_image_iid": null + } +}, { "model": "documents.corpus", - "pk": "2aeff5c5-69c0-4017-9104-636572f95b6f", + "pk": "1f7e82ec-4094-4397-b729-ec424ea7a37f", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", "name": "Unit Tests", "description": "", - "repository": "71ea33be-c05f-4813-9222-0d66e4342e71", + "repository": "d0cd8a85-8f30-43e1-ba19-7bd0dacb2041", "public": true } }, { "model": "documents.elementtype", - "pk": "04497bf1-b027-4ff4-b986-02cb530fd7b2", + "pk": "33d93a96-58a9-4a7c-be54-12d4691f4e81", "fields": { - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", "slug": "text_line", "display_name": "Line", "folder": false, @@ -47,359 +118,359 @@ }, { "model": "documents.elementtype", - "pk": "390071fb-febb-4982-807f-cabe1e803015", + "pk": "3bd6b808-4ced-41f5-8ae0-bf00804fcbaa", "fields": { - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "slug": "page", - "display_name": "Page", - "folder": false, + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "slug": "volume", + "display_name": "Volume", + "folder": true, "allowed_transcription": null } }, { "model": "documents.elementtype", - "pk": "5379fa38-d26e-4545-bbde-860b0ad5ad1b", + "pk": "a8c815f0-258f-4025-8f9b-f3bd6a87904c", "fields": { - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "slug": "act", - "display_name": "Act", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "slug": "surface", + "display_name": "Surface", "folder": false, "allowed_transcription": null } }, { "model": "documents.elementtype", - "pk": "8ddf6773-dd69-42b2-8566-5d6cdd9b2358", + "pk": "aad1941d-d7dd-485f-8cf3-90487ac522c8", "fields": { - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "slug": "volume", - "display_name": "Volume", - "folder": true, + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "slug": "page", + "display_name": "Page", + "folder": false, "allowed_transcription": null } }, { "model": "documents.elementtype", - "pk": "c5d42d12-22d1-4f73-92a1-aa080ebee4cc", + "pk": "bff45072-bc1b-408d-bd1f-b3ffd22d8796", "fields": { - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "slug": "surface", - "display_name": "Surface", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "slug": "act", + "display_name": "Act", "folder": false, "allowed_transcription": null } }, { "model": "documents.elementpath", - "pk": "184acdab-53dc-4b26-8aca-431e69031132", + "pk": "0355c4b6-bb16-474e-9b7b-bb86077339f3", "fields": { - "element": "a239c221-e169-4c28-a201-eadbb954121e", - "path": "[\"65069fcc-75df-443f-8dc2-4c8334f488b0\"]", + "element": "f3981e96-ed95-43a0-b1ea-fd288c55f5b3", + "path": "[\"3c4bce04-3ae8-4f17-86b0-46bc25408b8f\", \"ccc2cfdb-2de5-4e42-8a1a-fc5e1041b21d\"]", "ordering": 0 } }, { "model": "documents.elementpath", - "pk": "24ea5001-5357-482e-883f-65b159ade0b6", + "pk": "0406c678-c1b1-41b2-a4bd-d85e83ccd230", "fields": { - "element": "80519bbf-cd39-4142-887c-8066bbb764af", - "path": "[\"0e2d02fa-b565-4336-8131-0f8a7e5f29aa\", \"c7cdbe39-71f4-4278-98a2-f39afb1c5595\"]", - "ordering": 0 + "element": "ccc2cfdb-2de5-4e42-8a1a-fc5e1041b21d", + "path": "[\"3c4bce04-3ae8-4f17-86b0-46bc25408b8f\"]", + "ordering": 2 } }, { "model": "documents.elementpath", - "pk": "29a651d1-ab51-4391-983a-091df8d314b9", + "pk": "0f73c6dc-07b3-494a-b2fd-692c9a19ce5a", "fields": { - "element": "4c511df6-2791-4b9e-bcf9-eabbcdba3e39", - "path": "[\"65069fcc-75df-443f-8dc2-4c8334f488b0\"]", - "ordering": 1 + "element": "9621c876-e7da-4d43-a5a7-82470dead663", + "path": "[\"3c4bce04-3ae8-4f17-86b0-46bc25408b8f\"]", + "ordering": 0 } }, { "model": "documents.elementpath", - "pk": "2f6644f4-e441-4103-b923-d8b0ae40b600", + "pk": "208dd6c4-5510-4ceb-b8b4-fef27680df72", "fields": { - "element": "239b6dfe-dcff-42a0-b90f-60bcab6dbd20", - "path": "[\"0e2d02fa-b565-4336-8131-0f8a7e5f29aa\", \"f61f9197-1012-412e-8649-7fb1caac7f4d\"]", - "ordering": 0 + "element": "cb69d995-2ce2-4404-a567-5598cf9dd231", + "path": "[\"3c4bce04-3ae8-4f17-86b0-46bc25408b8f\"]", + "ordering": 1 } }, { "model": "documents.elementpath", - "pk": "43bf2565-714b-4868-82c6-3752e2edb61c", + "pk": "269ebcc7-7b11-43c9-a6cd-94d1ee99b03a", "fields": { - "element": "bc88e446-5145-4d77-a1f4-4c4936df28f2", - "path": "[\"0e2d02fa-b565-4336-8131-0f8a7e5f29aa\", \"c7cdbe39-71f4-4278-98a2-f39afb1c5595\"]", - "ordering": 1 + "element": "dbfa2c38-8664-447a-bb09-215cc86c6ab4", + "path": "[\"209e1e3b-5808-43bf-99b7-801959d6c807\"]", + "ordering": 2 } }, { "model": "documents.elementpath", - "pk": "469b4efa-3b20-4b7e-950f-035ef208b9ca", + "pk": "287575b8-9b19-49bd-adab-a241385191f4", "fields": { - "element": "c7cdbe39-71f4-4278-98a2-f39afb1c5595", - "path": "[\"0e2d02fa-b565-4336-8131-0f8a7e5f29aa\"]", - "ordering": 1 + "element": "f5535f84-2ca7-4853-9ab6-44606a8dc462", + "path": "[\"3c4bce04-3ae8-4f17-86b0-46bc25408b8f\", \"9621c876-e7da-4d43-a5a7-82470dead663\"]", + "ordering": 0 } }, { "model": "documents.elementpath", - "pk": "4c292f04-abed-4141-989e-2a262907ae9d", + "pk": "36cc34f3-8d0b-43cb-9040-7169471a03d4", "fields": { - "element": "d06ada28-259e-4994-9ca2-75b4af5a2882", - "path": "[\"0e2d02fa-b565-4336-8131-0f8a7e5f29aa\"]", - "ordering": 3 + "element": "564aa56f-b257-445c-9930-4b6110628c09", + "path": "[\"3c4bce04-3ae8-4f17-86b0-46bc25408b8f\"]", + "ordering": 2 } }, { "model": "documents.elementpath", - "pk": "5b0423e0-1a67-4b1f-9073-cea0c6810d95", + "pk": "38df3e8b-d824-4862-b7b5-580065b2011b", "fields": { - "element": "925d8acd-88a1-434e-91d2-fbb59a830b50", - "path": "[\"0e2d02fa-b565-4336-8131-0f8a7e5f29aa\"]", - "ordering": 0 + "element": "c0ec4456-f6a2-4253-a876-6eba4f96f863", + "path": "[\"3c4bce04-3ae8-4f17-86b0-46bc25408b8f\"]", + "ordering": 1 } }, { "model": "documents.elementpath", - "pk": "5d0a6638-c04f-40c2-96cb-d39cc1dd0421", + "pk": "3a6d0696-1ca2-4f83-a6dc-25a859482ebc", "fields": { - "element": "ed5a9ff4-46c2-4caa-8f85-a5bcdca18874", - "path": "[\"0e2d02fa-b565-4336-8131-0f8a7e5f29aa\", \"4396166b-2c68-4938-81bb-1d4e86b4b6e7\"]", + "element": "8f92f79c-471a-4280-9530-66ec406ab8b2", + "path": "[\"3c4bce04-3ae8-4f17-86b0-46bc25408b8f\"]", "ordering": 0 } }, { "model": "documents.elementpath", - "pk": "650d9dc0-7e0c-4f61-a248-b73e32b07102", + "pk": "582355b4-4352-4277-b6dd-62c6a8dfbf88", "fields": { - "element": "094936fd-546d-426b-86e6-b11fae5cc5ee", - "path": "[\"0e2d02fa-b565-4336-8131-0f8a7e5f29aa\", \"3a784a2e-c07e-42c0-a79c-53e338e68345\"]", + "element": "d7b6b144-88cb-4c47-a380-a84339773dda", + "path": "[\"3c4bce04-3ae8-4f17-86b0-46bc25408b8f\", \"cb69d995-2ce2-4404-a567-5598cf9dd231\"]", "ordering": 0 } }, { "model": "documents.elementpath", - "pk": "7520e39c-e5ce-437f-b341-d4a63212d73b", + "pk": "7abb9de4-a62f-49e4-979f-8975fe2e1111", "fields": { - "element": "3a784a2e-c07e-42c0-a79c-53e338e68345", - "path": "[\"0e2d02fa-b565-4336-8131-0f8a7e5f29aa\"]", - "ordering": 4 + "element": "02d0fa30-2a2d-4972-a069-626c629357a4", + "path": "[\"3c4bce04-3ae8-4f17-86b0-46bc25408b8f\", \"d19ded5f-c50c-4cc6-a0cf-4463e2f2df68\"]", + "ordering": 0 } }, { "model": "documents.elementpath", - "pk": "76e22b0c-4a75-4ea8-9915-185e78b8ffe1", + "pk": "a30e4bb0-b337-4718-a46b-53fc390393d0", "fields": { - "element": "f61f9197-1012-412e-8649-7fb1caac7f4d", - "path": "[\"0e2d02fa-b565-4336-8131-0f8a7e5f29aa\"]", - "ordering": 2 + "element": "7c022411-eb2c-4f06-9387-5d8418a0bf33", + "path": "[\"3c4bce04-3ae8-4f17-86b0-46bc25408b8f\"]", + "ordering": 3 } }, { "model": "documents.elementpath", - "pk": "8f3ced3f-d30a-40d0-9096-068d3a33dd28", + "pk": "a47f8cec-6c57-4d9d-a7f8-0ab9ab56ab44", "fields": { - "element": "0124d2f5-047f-4537-b0ea-cf641cffffb1", - "path": "[\"0e2d02fa-b565-4336-8131-0f8a7e5f29aa\", \"d06ada28-259e-4994-9ca2-75b4af5a2882\"]", + "element": "b09ebead-3440-4040-8b82-5dc2bae4d2d9", + "path": "[\"3c4bce04-3ae8-4f17-86b0-46bc25408b8f\", \"8f92f79c-471a-4280-9530-66ec406ab8b2\"]", "ordering": 0 } }, { "model": "documents.elementpath", - "pk": "963e241b-be33-45d0-b19a-901a67df00fb", + "pk": "b1b9f9f3-f543-4c57-aa49-a0aa716f1b71", "fields": { - "element": "5131c496-2487-4640-a972-f1071dfd4328", - "path": "[\"0e2d02fa-b565-4336-8131-0f8a7e5f29aa\", \"925d8acd-88a1-434e-91d2-fbb59a830b50\"]", + "element": "7e4d2f71-f52a-44a6-8cb5-f209a0b82408", + "path": "[\"209e1e3b-5808-43bf-99b7-801959d6c807\"]", "ordering": 0 } }, { "model": "documents.elementpath", - "pk": "c710c283-f76e-4a5c-82a9-9c9c91d20dc9", + "pk": "bc93dbca-6436-4601-9ecd-0ab08972b309", "fields": { - "element": "079ac524-4c94-45dc-92fe-74e77723914b", - "path": "[\"0e2d02fa-b565-4336-8131-0f8a7e5f29aa\"]", - "ordering": 2 + "element": "51585cf0-35b6-4b13-a445-37bed0aae13b", + "path": "[\"3c4bce04-3ae8-4f17-86b0-46bc25408b8f\", \"7c022411-eb2c-4f06-9387-5d8418a0bf33\"]", + "ordering": 0 } }, { "model": "documents.elementpath", - "pk": "ca1d8541-59b9-445f-a0bc-c84db6fdc4af", + "pk": "d47680ce-4ab8-4eb4-8cbe-cf06373ed654", "fields": { - "element": "337803ea-3774-4f50-947b-a8e52c52309d", - "path": "[\"65069fcc-75df-443f-8dc2-4c8334f488b0\"]", - "ordering": 2 + "element": "d19ded5f-c50c-4cc6-a0cf-4463e2f2df68", + "path": "[\"3c4bce04-3ae8-4f17-86b0-46bc25408b8f\"]", + "ordering": 4 } }, { "model": "documents.elementpath", - "pk": "cf970778-0ca2-417c-b4e5-05bcf696b96a", + "pk": "f593ed74-c825-44fa-a7da-a0d9776f2e0b", "fields": { - "element": "913eca56-5a1f-4006-af8b-100a44a5e1a9", - "path": "[\"0e2d02fa-b565-4336-8131-0f8a7e5f29aa\"]", + "element": "56a2302d-e027-4724-85be-c4113ff2a243", + "path": "[\"3c4bce04-3ae8-4f17-86b0-46bc25408b8f\", \"cb69d995-2ce2-4404-a567-5598cf9dd231\"]", "ordering": 1 } }, { "model": "documents.elementpath", - "pk": "f19395e9-5c44-4b74-b580-4f354f15da9d", + "pk": "fc3dfb9d-1763-4892-95a9-1c8adeb8f41c", "fields": { - "element": "4396166b-2c68-4938-81bb-1d4e86b4b6e7", - "path": "[\"0e2d02fa-b565-4336-8131-0f8a7e5f29aa\"]", - "ordering": 0 + "element": "4e9de67b-6e4f-46b7-936e-34ed9692900b", + "path": "[\"209e1e3b-5808-43bf-99b7-801959d6c807\"]", + "ordering": 1 } }, { "model": "documents.element", - "pk": "0124d2f5-047f-4537-b0ea-cf641cffffb1", + "pk": "02d0fa30-2a2d-4972-a069-626c629357a4", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "c5d42d12-22d1-4f73-92a1-aa080ebee4cc", - "name": "Surface E", - "zone": "ab1ba0c5-0238-4587-9154-3344b1e30a85", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "a8c815f0-258f-4025-8f9b-f3bd6a87904c", + "name": "Surface F", + "zone": "d2e7ee12-14fa-46c8-a360-f5b31939052a", "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "079ac524-4c94-45dc-92fe-74e77723914b", + "pk": "209e1e3b-5808-43bf-99b7-801959d6c807", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "390071fb-febb-4982-807f-cabe1e803015", - "name": "Volume 1, page 2r", - "zone": "49adab61-dd91-493b-98d0-8e66761e6b44", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "3bd6b808-4ced-41f5-8ae0-bf00804fcbaa", + "name": "Volume 2", + "zone": null, "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "094936fd-546d-426b-86e6-b11fae5cc5ee", + "pk": "3c4bce04-3ae8-4f17-86b0-46bc25408b8f", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "c5d42d12-22d1-4f73-92a1-aa080ebee4cc", - "name": "Surface F", - "zone": "ecdd78a6-c197-41fe-8a1d-857e57f31526", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "3bd6b808-4ced-41f5-8ae0-bf00804fcbaa", + "name": "Volume 1", + "zone": null, "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "0e2d02fa-b565-4336-8131-0f8a7e5f29aa", + "pk": "4e9de67b-6e4f-46b7-936e-34ed9692900b", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "8ddf6773-dd69-42b2-8566-5d6cdd9b2358", - "name": "Volume 1", - "zone": null, + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "aad1941d-d7dd-485f-8cf3-90487ac522c8", + "name": "Volume 2, page 1v", + "zone": "e67eba1f-4993-492e-9ca0-67451ceb094c", "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "239b6dfe-dcff-42a0-b90f-60bcab6dbd20", + "pk": "51585cf0-35b6-4b13-a445-37bed0aae13b", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "c5d42d12-22d1-4f73-92a1-aa080ebee4cc", - "name": "Surface D", - "zone": "da3f96a9-ad6d-476a-9c0c-7a08457e9ca5", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "a8c815f0-258f-4025-8f9b-f3bd6a87904c", + "name": "Surface E", + "zone": "f3b62073-8fe4-46c9-b7bf-012c3014359b", "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "337803ea-3774-4f50-947b-a8e52c52309d", + "pk": "564aa56f-b257-445c-9930-4b6110628c09", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "390071fb-febb-4982-807f-cabe1e803015", - "name": "Volume 2, page 2r", - "zone": "06f88cf0-c12e-4f33-a7ba-e3adb15b6211", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "aad1941d-d7dd-485f-8cf3-90487ac522c8", + "name": "Volume 1, page 2r", + "zone": "20f0abb7-3aac-460b-b1af-b75ed7dab550", "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "3a784a2e-c07e-42c0-a79c-53e338e68345", + "pk": "56a2302d-e027-4724-85be-c4113ff2a243", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "5379fa38-d26e-4545-bbde-860b0ad5ad1b", - "name": "Act 5", - "zone": null, + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "a8c815f0-258f-4025-8f9b-f3bd6a87904c", + "name": "Surface C", + "zone": "dda78215-f30b-497f-aedb-fac49055b667", "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "4396166b-2c68-4938-81bb-1d4e86b4b6e7", + "pk": "7c022411-eb2c-4f06-9387-5d8418a0bf33", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "390071fb-febb-4982-807f-cabe1e803015", - "name": "Volume 1, page 1r", - "zone": "b833caac-0665-4a51-8022-17bcf74ca629", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "bff45072-bc1b-408d-bd1f-b3ffd22d8796", + "name": "Act 4", + "zone": null, "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "4c511df6-2791-4b9e-bcf9-eabbcdba3e39", + "pk": "7e4d2f71-f52a-44a6-8cb5-f209a0b82408", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "390071fb-febb-4982-807f-cabe1e803015", - "name": "Volume 2, page 1v", - "zone": "f975ebab-d0e4-44f4-87fd-6c36702de2c8", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "aad1941d-d7dd-485f-8cf3-90487ac522c8", + "name": "Volume 2, page 1r", + "zone": "541c027b-3e0b-42f6-acf6-abcc49ff5f1e", "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "5131c496-2487-4640-a972-f1071dfd4328", + "pk": "8f92f79c-471a-4280-9530-66ec406ab8b2", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "c5d42d12-22d1-4f73-92a1-aa080ebee4cc", - "name": "Surface A", - "zone": "0132634c-7dec-4a02-96f0-3d3f8205ee34", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "aad1941d-d7dd-485f-8cf3-90487ac522c8", + "name": "Volume 1, page 1r", + "zone": "5bd58b5d-8ed2-4e56-a466-b863101dfdc6", "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "65069fcc-75df-443f-8dc2-4c8334f488b0", + "pk": "9621c876-e7da-4d43-a5a7-82470dead663", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "8ddf6773-dd69-42b2-8566-5d6cdd9b2358", - "name": "Volume 2", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "bff45072-bc1b-408d-bd1f-b3ffd22d8796", + "name": "Act 1", "zone": null, "source": null, "worker_version": null @@ -407,41 +478,41 @@ }, { "model": "documents.element", - "pk": "80519bbf-cd39-4142-887c-8066bbb764af", + "pk": "b09ebead-3440-4040-8b82-5dc2bae4d2d9", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "c5d42d12-22d1-4f73-92a1-aa080ebee4cc", - "name": "Surface B", - "zone": "1caadaf8-131c-4c10-b41d-8d6098137bf1", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "33d93a96-58a9-4a7c-be54-12d4691f4e81", + "name": "Text line", + "zone": "59c89a4e-b961-4158-8107-f24463b40fca", "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "913eca56-5a1f-4006-af8b-100a44a5e1a9", + "pk": "c0ec4456-f6a2-4253-a876-6eba4f96f863", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "390071fb-febb-4982-807f-cabe1e803015", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "aad1941d-d7dd-485f-8cf3-90487ac522c8", "name": "Volume 1, page 1v", - "zone": "d1dab6ef-17d0-4117-83e5-ce81ba83ca78", + "zone": "dda78215-f30b-497f-aedb-fac49055b667", "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "925d8acd-88a1-434e-91d2-fbb59a830b50", + "pk": "cb69d995-2ce2-4404-a567-5598cf9dd231", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "5379fa38-d26e-4545-bbde-860b0ad5ad1b", - "name": "Act 1", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "bff45072-bc1b-408d-bd1f-b3ffd22d8796", + "name": "Act 2", "zone": null, "source": null, "worker_version": null @@ -449,91 +520,91 @@ }, { "model": "documents.element", - "pk": "a239c221-e169-4c28-a201-eadbb954121e", + "pk": "ccc2cfdb-2de5-4e42-8a1a-fc5e1041b21d", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "390071fb-febb-4982-807f-cabe1e803015", - "name": "Volume 2, page 1r", - "zone": "7cb72016-6e5b-4822-92b3-907ed0afaf4d", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "bff45072-bc1b-408d-bd1f-b3ffd22d8796", + "name": "Act 3", + "zone": null, "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "bc88e446-5145-4d77-a1f4-4c4936df28f2", + "pk": "d19ded5f-c50c-4cc6-a0cf-4463e2f2df68", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "c5d42d12-22d1-4f73-92a1-aa080ebee4cc", - "name": "Surface C", - "zone": "d1dab6ef-17d0-4117-83e5-ce81ba83ca78", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "bff45072-bc1b-408d-bd1f-b3ffd22d8796", + "name": "Act 5", + "zone": null, "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "c7cdbe39-71f4-4278-98a2-f39afb1c5595", + "pk": "d7b6b144-88cb-4c47-a380-a84339773dda", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "5379fa38-d26e-4545-bbde-860b0ad5ad1b", - "name": "Act 2", - "zone": null, + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "a8c815f0-258f-4025-8f9b-f3bd6a87904c", + "name": "Surface B", + "zone": "b9cb9d9d-8de0-4fcf-8063-a5eb30634b8e", "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "d06ada28-259e-4994-9ca2-75b4af5a2882", + "pk": "dbfa2c38-8664-447a-bb09-215cc86c6ab4", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "5379fa38-d26e-4545-bbde-860b0ad5ad1b", - "name": "Act 4", - "zone": null, + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "aad1941d-d7dd-485f-8cf3-90487ac522c8", + "name": "Volume 2, page 2r", + "zone": "543950e5-031d-41d1-83fd-7365c193c916", "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "ed5a9ff4-46c2-4caa-8f85-a5bcdca18874", + "pk": "f3981e96-ed95-43a0-b1ea-fd288c55f5b3", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "04497bf1-b027-4ff4-b986-02cb530fd7b2", - "name": "Text line", - "zone": "3df20773-faa5-4d45-ad62-bc3affb526b7", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "a8c815f0-258f-4025-8f9b-f3bd6a87904c", + "name": "Surface D", + "zone": "3e6c6344-4dec-4609-b12d-14fd65c32664", "source": null, "worker_version": null } }, { "model": "documents.element", - "pk": "f61f9197-1012-412e-8649-7fb1caac7f4d", + "pk": "f5535f84-2ca7-4853-9ab6-44606a8dc462", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "5379fa38-d26e-4545-bbde-860b0ad5ad1b", - "name": "Act 3", - "zone": null, + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "a8c815f0-258f-4025-8f9b-f3bd6a87904c", + "name": "Surface A", + "zone": "53ad7c0c-efcd-4001-be5b-298d1e8498b6", "source": null, "worker_version": null } }, { "model": "documents.datasource", - "pk": "b080fedb-cb71-4415-a5f8-b7fbd7ea51a2", + "pk": "9ad06f06-000c-4d01-8038-1afc2e73c8e1", "fields": { "type": "recognizer", "slug": "test", @@ -544,7 +615,7 @@ }, { "model": "documents.datasource", - "pk": "fbc73e49-39d4-4eb5-a06a-8c3f36543abd", + "pk": "c357f678-9e18-4179-a9ee-4f35fdf26cd8", "fields": { "type": "classifier", "slug": "test", @@ -555,12 +626,12 @@ }, { "model": "documents.transcription", - "pk": "0baf8b02-0818-44a6-9e5f-98e72ea8360e", + "pk": "2578a1cf-3e57-4a15-b4cb-a0008c13a563", "fields": { - "element": "4396166b-2c68-4938-81bb-1d4e86b4b6e7", + "element": "8f92f79c-471a-4280-9530-66ec406ab8b2", "type": "word", - "zone": "3df20773-faa5-4d45-ad62-bc3affb526b7", - "source": "b080fedb-cb71-4415-a5f8-b7fbd7ea51a2", + "zone": "59c89a4e-b961-4158-8107-f24463b40fca", + "source": "9ad06f06-000c-4d01-8038-1afc2e73c8e1", "worker_version": null, "text": "ROY", "score": 1.0 @@ -568,25 +639,25 @@ }, { "model": "documents.transcription", - "pk": "325f7a71-6c2b-4fed-8b80-b10de5b085d4", + "pk": "4fc2945e-e4be-44d6-a839-c3149cbc66e0", "fields": { - "element": "079ac524-4c94-45dc-92fe-74e77723914b", + "element": "564aa56f-b257-445c-9930-4b6110628c09", "type": "word", - "zone": "45abfacd-dfd0-46f8-a981-84e384997000", - "source": "b080fedb-cb71-4415-a5f8-b7fbd7ea51a2", + "zone": "a2723514-109f-4b13-8336-e0128c49aee4", + "source": "9ad06f06-000c-4d01-8038-1afc2e73c8e1", "worker_version": null, - "text": "PARIS", + "text": "ROY", "score": 1.0 } }, { "model": "documents.transcription", - "pk": "352445b1-bb27-45fe-9425-c885156cddf1", + "pk": "51785975-0bf3-4bd1-8002-ae8c21dacbd4", "fields": { - "element": "913eca56-5a1f-4006-af8b-100a44a5e1a9", + "element": "c0ec4456-f6a2-4253-a876-6eba4f96f863", "type": "word", - "zone": "93b10936-a485-43ed-b9fb-82cec3a45586", - "source": "b080fedb-cb71-4415-a5f8-b7fbd7ea51a2", + "zone": "2e3f07cc-d8cb-4735-bed0-63d4d109d893", + "source": "9ad06f06-000c-4d01-8038-1afc2e73c8e1", "worker_version": null, "text": "PARIS", "score": 1.0 @@ -594,90 +665,90 @@ }, { "model": "documents.transcription", - "pk": "562cb1c9-5d84-493e-9d86-20a970331856", + "pk": "72409ca8-98ff-4055-98e8-5b5e8620e1fe", "fields": { - "element": "079ac524-4c94-45dc-92fe-74e77723914b", + "element": "c0ec4456-f6a2-4253-a876-6eba4f96f863", "type": "word", - "zone": "c8c78eb2-f8d8-40e3-9f46-31b39a6a5cea", - "source": "b080fedb-cb71-4415-a5f8-b7fbd7ea51a2", + "zone": "de6f5a26-52fd-4361-b30e-08b98b9d480a", + "source": "9ad06f06-000c-4d01-8038-1afc2e73c8e1", "worker_version": null, - "text": "ROY", + "text": "DATUM", "score": 1.0 } }, { "model": "documents.transcription", - "pk": "63cb6a02-089f-4f9a-aef1-2b9c23cc5100", + "pk": "81e2a90b-d518-4280-b71b-7cdc24587472", "fields": { - "element": "4396166b-2c68-4938-81bb-1d4e86b4b6e7", + "element": "564aa56f-b257-445c-9930-4b6110628c09", "type": "word", - "zone": "20eb0629-ed33-4174-92d9-e83f73541283", - "source": "b080fedb-cb71-4415-a5f8-b7fbd7ea51a2", + "zone": "658a1c75-a4de-4842-8a09-2a51c22c8269", + "source": "9ad06f06-000c-4d01-8038-1afc2e73c8e1", "worker_version": null, - "text": "DATUM", + "text": "PARIS", "score": 1.0 } }, { "model": "documents.transcription", - "pk": "aed93356-579f-4114-9f34-20252af6e591", + "pk": "d4e38d93-48dc-4c46-881f-fe85ddfd01da", "fields": { - "element": "079ac524-4c94-45dc-92fe-74e77723914b", + "element": "8f92f79c-471a-4280-9530-66ec406ab8b2", "type": "word", - "zone": "4a4d6030-b40e-4bcd-bea8-ba6e0cc938b8", - "source": "b080fedb-cb71-4415-a5f8-b7fbd7ea51a2", + "zone": "2d6cbfa0-917e-4f3e-91db-3e050f236922", + "source": "9ad06f06-000c-4d01-8038-1afc2e73c8e1", "worker_version": null, - "text": "DATUM", + "text": "PARIS", "score": 1.0 } }, { "model": "documents.transcription", - "pk": "bfcadc4e-df0a-4bc1-856c-4a1e62d17bd9", + "pk": "d5297c59-e7b8-4c03-8b53-d84347ec726c", "fields": { - "element": "4396166b-2c68-4938-81bb-1d4e86b4b6e7", + "element": "8f92f79c-471a-4280-9530-66ec406ab8b2", "type": "word", - "zone": "1a8a7098-1452-423a-8480-4e352721017f", - "source": "b080fedb-cb71-4415-a5f8-b7fbd7ea51a2", + "zone": "1323086e-7117-4454-b6d2-d2e9b9b30251", + "source": "9ad06f06-000c-4d01-8038-1afc2e73c8e1", "worker_version": null, - "text": "PARIS", + "text": "DATUM", "score": 1.0 } }, { "model": "documents.transcription", - "pk": "c00d9cfa-e46d-49cc-b077-5d9e569ad87a", + "pk": "daef6593-28c3-4b81-a693-e1ec81f52718", "fields": { - "element": "913eca56-5a1f-4006-af8b-100a44a5e1a9", + "element": "c0ec4456-f6a2-4253-a876-6eba4f96f863", "type": "word", - "zone": "77b9c118-eeb5-4e5f-8cac-4c3a7cf5357e", - "source": "b080fedb-cb71-4415-a5f8-b7fbd7ea51a2", + "zone": "4ae281d2-de97-42dc-ac66-d3edc93bf92e", + "source": "9ad06f06-000c-4d01-8038-1afc2e73c8e1", "worker_version": null, - "text": "DATUM", + "text": "ROY", "score": 1.0 } }, { "model": "documents.transcription", - "pk": "dbf30003-6ab7-4718-a5ef-dd0e9aeb5a49", + "pk": "e275ebac-db1d-48df-90d5-0513464f4ab0", "fields": { - "element": "913eca56-5a1f-4006-af8b-100a44a5e1a9", + "element": "564aa56f-b257-445c-9930-4b6110628c09", "type": "word", - "zone": "87d0075b-a84c-4b72-9fba-dcdb875830ac", - "source": "b080fedb-cb71-4415-a5f8-b7fbd7ea51a2", + "zone": "021f8b5e-4963-4638-a24f-fa99114ffd17", + "source": "9ad06f06-000c-4d01-8038-1afc2e73c8e1", "worker_version": null, - "text": "ROY", + "text": "DATUM", "score": 1.0 } }, { "model": "documents.transcription", - "pk": "dc2b4427-07e3-4748-a7a2-ec2ec05d5b7a", + "pk": "ea21f8c6-1ecf-4be8-848b-af333c8b83a1", "fields": { - "element": "4396166b-2c68-4938-81bb-1d4e86b4b6e7", + "element": "8f92f79c-471a-4280-9530-66ec406ab8b2", "type": "page", "zone": null, - "source": "b080fedb-cb71-4415-a5f8-b7fbd7ea51a2", + "source": "9ad06f06-000c-4d01-8038-1afc2e73c8e1", "worker_version": null, "text": "Lorem ipsum dolor sit amet", "score": 1.0 @@ -685,39 +756,39 @@ }, { "model": "documents.allowedmetadata", - "pk": "20b940e9-606c-42d5-bb3d-b7ca659348c5", + "pk": "0f90ca4d-c698-4a14-89fc-32c153e6a5fd", "fields": { - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", "type": "text", "name": "folio" } }, { "model": "documents.allowedmetadata", - "pk": "9c34ab1c-8ef0-4d0e-963c-7b10704e4a65", + "pk": "1ab75f14-57ca-4c05-a9fb-f10c082f4206", "fields": { - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "date", - "name": "date" + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "location", + "name": "location" } }, { "model": "documents.allowedmetadata", - "pk": "c468f194-a05a-49ce-9053-b230f27bebc2", + "pk": "90cf5544-2b0a-465a-aae4-c7de6ade0592", "fields": { - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", - "type": "location", - "name": "location" + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", + "type": "date", + "name": "date" } }, { "model": "documents.metadata", - "pk": "0c49e0ad-f122-4da0-95a1-6944baf5eed4", + "pk": "0be7aa65-fa4d-4cea-bba2-86748478b595", "fields": { - "element": "f61f9197-1012-412e-8649-7fb1caac7f4d", - "name": "number", + "element": "564aa56f-b257-445c-9930-4b6110628c09", + "name": "folio", "type": "text", - "value": "3", + "value": "2r", "revision": null, "index": 0, "entity": null @@ -725,12 +796,12 @@ }, { "model": "documents.metadata", - "pk": "23fee0c5-6536-4ea1-9f5d-453f1630765f", + "pk": "12069432-7670-4378-a918-23daf27ea172", "fields": { - "element": "337803ea-3774-4f50-947b-a8e52c52309d", - "name": "folio", + "element": "7c022411-eb2c-4f06-9387-5d8418a0bf33", + "name": "number", "type": "text", - "value": "2r", + "value": "4", "revision": null, "index": 0, "entity": null @@ -738,12 +809,12 @@ }, { "model": "documents.metadata", - "pk": "34096e03-1738-4ee8-b098-be723c89c773", + "pk": "14e7fd76-4c9b-4e45-b01c-f6ac04b4d17c", "fields": { - "element": "4c511df6-2791-4b9e-bcf9-eabbcdba3e39", - "name": "folio", + "element": "cb69d995-2ce2-4404-a567-5598cf9dd231", + "name": "number", "type": "text", - "value": "1v", + "value": "2", "revision": null, "index": 0, "entity": null @@ -751,12 +822,12 @@ }, { "model": "documents.metadata", - "pk": "42014bf3-6f29-4ed2-b042-ca7f192faf6e", + "pk": "2f82730b-fc55-485c-869d-7aa2214aafef", "fields": { - "element": "925d8acd-88a1-434e-91d2-fbb59a830b50", - "name": "number", + "element": "c0ec4456-f6a2-4253-a876-6eba4f96f863", + "name": "folio", "type": "text", - "value": "1", + "value": "1v", "revision": null, "index": 0, "entity": null @@ -764,12 +835,12 @@ }, { "model": "documents.metadata", - "pk": "4be6d63e-2f0c-47e4-b891-2b137f1c58be", + "pk": "63ff193e-fd67-4c2d-b52d-3c99a49f1131", "fields": { - "element": "4396166b-2c68-4938-81bb-1d4e86b4b6e7", + "element": "dbfa2c38-8664-447a-bb09-215cc86c6ab4", "name": "folio", "type": "text", - "value": "1r", + "value": "2r", "revision": null, "index": 0, "entity": null @@ -777,12 +848,12 @@ }, { "model": "documents.metadata", - "pk": "792f385f-7056-4308-b520-f97fb98fa3d4", + "pk": "759c2edc-6e7b-4f96-9cd9-0daa38d9757a", "fields": { - "element": "079ac524-4c94-45dc-92fe-74e77723914b", + "element": "4e9de67b-6e4f-46b7-936e-34ed9692900b", "name": "folio", "type": "text", - "value": "2r", + "value": "1v", "revision": null, "index": 0, "entity": null @@ -790,12 +861,12 @@ }, { "model": "documents.metadata", - "pk": "a596d55f-c8c1-425a-a125-6d6269cbc21f", + "pk": "79c508f3-4288-4a1b-8f1f-19af1a057e3e", "fields": { - "element": "c7cdbe39-71f4-4278-98a2-f39afb1c5595", + "element": "d19ded5f-c50c-4cc6-a0cf-4463e2f2df68", "name": "number", "type": "text", - "value": "2", + "value": "5", "revision": null, "index": 0, "entity": null @@ -803,12 +874,12 @@ }, { "model": "documents.metadata", - "pk": "a8269161-8417-4498-b099-298ef709b675", + "pk": "7f3688fb-3a16-4cba-b218-47a372eb5480", "fields": { - "element": "a239c221-e169-4c28-a201-eadbb954121e", - "name": "folio", + "element": "9621c876-e7da-4d43-a5a7-82470dead663", + "name": "number", "type": "text", - "value": "1r", + "value": "1", "revision": null, "index": 0, "entity": null @@ -816,12 +887,12 @@ }, { "model": "documents.metadata", - "pk": "aa3c6987-42d6-49e4-881a-a2c668b0cae9", + "pk": "d86e7d8d-2dc8-4ac7-ac5e-d8aff8df4548", "fields": { - "element": "d06ada28-259e-4994-9ca2-75b4af5a2882", - "name": "number", + "element": "7e4d2f71-f52a-44a6-8cb5-f209a0b82408", + "name": "folio", "type": "text", - "value": "4", + "value": "1r", "revision": null, "index": 0, "entity": null @@ -829,12 +900,12 @@ }, { "model": "documents.metadata", - "pk": "d68375ea-8cbe-437f-a59c-b799ef6e659e", + "pk": "d9c74f49-670d-4b37-a21e-60ca50059cda", "fields": { - "element": "913eca56-5a1f-4006-af8b-100a44a5e1a9", - "name": "folio", + "element": "ccc2cfdb-2de5-4e42-8a1a-fc5e1041b21d", + "name": "number", "type": "text", - "value": "1v", + "value": "3", "revision": null, "index": 0, "entity": null @@ -842,12 +913,12 @@ }, { "model": "documents.metadata", - "pk": "ea0cd0a0-6ce9-41d8-94c6-3304c7d9a7f9", + "pk": "f4103a83-94eb-4634-8cd3-32db7e94ac1e", "fields": { - "element": "3a784a2e-c07e-42c0-a79c-53e338e68345", - "name": "number", + "element": "8f92f79c-471a-4280-9530-66ec406ab8b2", + "name": "folio", "type": "text", - "value": "5", + "value": "1r", "revision": null, "index": 0, "entity": null @@ -871,12 +942,12 @@ }, { "model": "images.image", - "pk": "18d5f671-6abe-4e16-9bb2-cfee82a17220", + "pk": "0a18ca58-69a7-44f8-b2ac-739a7a978cf2", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", "server": 1, - "path": "img1", + "path": "img3", "width": 1000, "height": 1000, "hash": null, @@ -885,12 +956,12 @@ }, { "model": "images.image", - "pk": "34603613-b450-4f52-8db8-fa0410d53355", + "pk": "7ce02a7c-877a-46bc-8557-cd87b6945d81", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", "server": 1, - "path": "img5", + "path": "img4", "width": 1000, "height": 1000, "hash": null, @@ -899,12 +970,12 @@ }, { "model": "images.image", - "pk": "67c8b3de-d245-46cb-b31e-4653493fab27", + "pk": "a415642f-af03-422d-acf2-a9fce1cf6ef1", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", "server": 1, - "path": "img4", + "path": "img2", "width": 1000, "height": 1000, "hash": null, @@ -913,12 +984,12 @@ }, { "model": "images.image", - "pk": "70ed4289-845b-4998-8a74-20925816c94b", + "pk": "c1f75796-3a1c-4e85-b8fa-43472a719312", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", "server": 1, - "path": "img2", + "path": "img5", "width": 1000, "height": 1000, "hash": null, @@ -927,12 +998,12 @@ }, { "model": "images.image", - "pk": "977247ec-49ee-4f6a-949d-03e267adef23", + "pk": "ddbb369c-a6ed-488c-9108-e996ade67b29", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", "server": 1, - "path": "img6", + "path": "img1", "width": 1000, "height": 1000, "hash": null, @@ -941,12 +1012,12 @@ }, { "model": "images.image", - "pk": "c3a900c3-7fe4-44b3-816d-ca69f8227570", + "pk": "e6df804d-82f7-420e-a562-fb3d265a2bec", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", "server": 1, - "path": "img3", + "path": "img6", "width": 1000, "height": 1000, "hash": null, @@ -955,209 +1026,209 @@ }, { "model": "images.zone", - "pk": "0132634c-7dec-4a02-96f0-3d3f8205ee34", + "pk": "021f8b5e-4963-4638-a24f-fa99114ffd17", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "18d5f671-6abe-4e16-9bb2-cfee82a17220", - "polygon": "LINEARRING (0 0, 0 600, 600 600, 600 0, 0 0)" + "image": "0a18ca58-69a7-44f8-b2ac-739a7a978cf2", + "polygon": "LINEARRING (700 700, 700 800, 800 800, 800 700, 700 700)" } }, { "model": "images.zone", - "pk": "06f88cf0-c12e-4f33-a7ba-e3adb15b6211", + "pk": "1323086e-7117-4454-b6d2-d2e9b9b30251", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "977247ec-49ee-4f6a-949d-03e267adef23", - "polygon": "LINEARRING (0 0, 0 1000, 1000 1000, 1000 0, 0 0)" + "image": "ddbb369c-a6ed-488c-9108-e996ade67b29", + "polygon": "LINEARRING (700 700, 700 800, 800 800, 800 700, 700 700)" } }, { "model": "images.zone", - "pk": "1a8a7098-1452-423a-8480-4e352721017f", + "pk": "20f0abb7-3aac-460b-b1af-b75ed7dab550", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "18d5f671-6abe-4e16-9bb2-cfee82a17220", - "polygon": "LINEARRING (100 100, 100 200, 200 200, 200 100, 100 100)" + "image": "0a18ca58-69a7-44f8-b2ac-739a7a978cf2", + "polygon": "LINEARRING (0 0, 0 1000, 1000 1000, 1000 0, 0 0)" } }, { "model": "images.zone", - "pk": "1caadaf8-131c-4c10-b41d-8d6098137bf1", + "pk": "2d6cbfa0-917e-4f3e-91db-3e050f236922", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "18d5f671-6abe-4e16-9bb2-cfee82a17220", - "polygon": "LINEARRING (600 600, 600 1000, 1000 1000, 1000 600, 600 600)" + "image": "ddbb369c-a6ed-488c-9108-e996ade67b29", + "polygon": "LINEARRING (100 100, 100 200, 200 200, 200 100, 100 100)" } }, { "model": "images.zone", - "pk": "20eb0629-ed33-4174-92d9-e83f73541283", + "pk": "2e3f07cc-d8cb-4735-bed0-63d4d109d893", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "18d5f671-6abe-4e16-9bb2-cfee82a17220", - "polygon": "LINEARRING (700 700, 700 800, 800 800, 800 700, 700 700)" + "image": "a415642f-af03-422d-acf2-a9fce1cf6ef1", + "polygon": "LINEARRING (100 100, 100 200, 200 200, 200 100, 100 100)" } }, { "model": "images.zone", - "pk": "3df20773-faa5-4d45-ad62-bc3affb526b7", + "pk": "3e6c6344-4dec-4609-b12d-14fd65c32664", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "18d5f671-6abe-4e16-9bb2-cfee82a17220", - "polygon": "LINEARRING (400 400, 400 500, 500 500, 500 400, 400 400)" + "image": "0a18ca58-69a7-44f8-b2ac-739a7a978cf2", + "polygon": "LINEARRING (0 0, 0 300, 300 300, 300 0, 0 0)" } }, { "model": "images.zone", - "pk": "45abfacd-dfd0-46f8-a981-84e384997000", + "pk": "4ae281d2-de97-42dc-ac66-d3edc93bf92e", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "c3a900c3-7fe4-44b3-816d-ca69f8227570", - "polygon": "LINEARRING (100 100, 100 200, 200 200, 200 100, 100 100)" + "image": "a415642f-af03-422d-acf2-a9fce1cf6ef1", + "polygon": "LINEARRING (400 400, 400 500, 500 500, 500 400, 400 400)" } }, { "model": "images.zone", - "pk": "49adab61-dd91-493b-98d0-8e66761e6b44", + "pk": "53ad7c0c-efcd-4001-be5b-298d1e8498b6", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "c3a900c3-7fe4-44b3-816d-ca69f8227570", - "polygon": "LINEARRING (0 0, 0 1000, 1000 1000, 1000 0, 0 0)" + "image": "ddbb369c-a6ed-488c-9108-e996ade67b29", + "polygon": "LINEARRING (0 0, 0 600, 600 600, 600 0, 0 0)" } }, { "model": "images.zone", - "pk": "4a4d6030-b40e-4bcd-bea8-ba6e0cc938b8", + "pk": "541c027b-3e0b-42f6-acf6-abcc49ff5f1e", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "c3a900c3-7fe4-44b3-816d-ca69f8227570", - "polygon": "LINEARRING (700 700, 700 800, 800 800, 800 700, 700 700)" + "image": "7ce02a7c-877a-46bc-8557-cd87b6945d81", + "polygon": "LINEARRING (0 0, 0 1000, 1000 1000, 1000 0, 0 0)" } }, { "model": "images.zone", - "pk": "77b9c118-eeb5-4e5f-8cac-4c3a7cf5357e", + "pk": "543950e5-031d-41d1-83fd-7365c193c916", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "70ed4289-845b-4998-8a74-20925816c94b", - "polygon": "LINEARRING (700 700, 700 800, 800 800, 800 700, 700 700)" + "image": "e6df804d-82f7-420e-a562-fb3d265a2bec", + "polygon": "LINEARRING (0 0, 0 1000, 1000 1000, 1000 0, 0 0)" } }, { "model": "images.zone", - "pk": "7cb72016-6e5b-4822-92b3-907ed0afaf4d", + "pk": "59c89a4e-b961-4158-8107-f24463b40fca", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "67c8b3de-d245-46cb-b31e-4653493fab27", - "polygon": "LINEARRING (0 0, 0 1000, 1000 1000, 1000 0, 0 0)" + "image": "ddbb369c-a6ed-488c-9108-e996ade67b29", + "polygon": "LINEARRING (400 400, 400 500, 500 500, 500 400, 400 400)" } }, { "model": "images.zone", - "pk": "87d0075b-a84c-4b72-9fba-dcdb875830ac", + "pk": "5bd58b5d-8ed2-4e56-a466-b863101dfdc6", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "70ed4289-845b-4998-8a74-20925816c94b", - "polygon": "LINEARRING (400 400, 400 500, 500 500, 500 400, 400 400)" + "image": "ddbb369c-a6ed-488c-9108-e996ade67b29", + "polygon": "LINEARRING (0 0, 0 1000, 1000 1000, 1000 0, 0 0)" } }, { "model": "images.zone", - "pk": "93b10936-a485-43ed-b9fb-82cec3a45586", + "pk": "658a1c75-a4de-4842-8a09-2a51c22c8269", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "70ed4289-845b-4998-8a74-20925816c94b", + "image": "0a18ca58-69a7-44f8-b2ac-739a7a978cf2", "polygon": "LINEARRING (100 100, 100 200, 200 200, 200 100, 100 100)" } }, { "model": "images.zone", - "pk": "ab1ba0c5-0238-4587-9154-3344b1e30a85", + "pk": "a2723514-109f-4b13-8336-e0128c49aee4", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "c3a900c3-7fe4-44b3-816d-ca69f8227570", - "polygon": "LINEARRING (300 300, 300 600, 600 600, 600 300, 300 300)" + "image": "0a18ca58-69a7-44f8-b2ac-739a7a978cf2", + "polygon": "LINEARRING (400 400, 400 500, 500 500, 500 400, 400 400)" } }, { "model": "images.zone", - "pk": "b833caac-0665-4a51-8022-17bcf74ca629", + "pk": "b9cb9d9d-8de0-4fcf-8063-a5eb30634b8e", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "18d5f671-6abe-4e16-9bb2-cfee82a17220", - "polygon": "LINEARRING (0 0, 0 1000, 1000 1000, 1000 0, 0 0)" + "image": "ddbb369c-a6ed-488c-9108-e996ade67b29", + "polygon": "LINEARRING (600 600, 600 1000, 1000 1000, 1000 600, 600 600)" } }, { "model": "images.zone", - "pk": "c8c78eb2-f8d8-40e3-9f46-31b39a6a5cea", + "pk": "d2e7ee12-14fa-46c8-a360-f5b31939052a", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "c3a900c3-7fe4-44b3-816d-ca69f8227570", - "polygon": "LINEARRING (400 400, 400 500, 500 500, 500 400, 400 400)" + "image": "0a18ca58-69a7-44f8-b2ac-739a7a978cf2", + "polygon": "LINEARRING (600 600, 600 1000, 1000 1000, 1000 600, 600 600)" } }, { "model": "images.zone", - "pk": "d1dab6ef-17d0-4117-83e5-ce81ba83ca78", + "pk": "dda78215-f30b-497f-aedb-fac49055b667", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "70ed4289-845b-4998-8a74-20925816c94b", + "image": "a415642f-af03-422d-acf2-a9fce1cf6ef1", "polygon": "LINEARRING (0 0, 0 1000, 1000 1000, 1000 0, 0 0)" } }, { "model": "images.zone", - "pk": "da3f96a9-ad6d-476a-9c0c-7a08457e9ca5", + "pk": "de6f5a26-52fd-4361-b30e-08b98b9d480a", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "c3a900c3-7fe4-44b3-816d-ca69f8227570", - "polygon": "LINEARRING (0 0, 0 300, 300 300, 300 0, 0 0)" + "image": "a415642f-af03-422d-acf2-a9fce1cf6ef1", + "polygon": "LINEARRING (700 700, 700 800, 800 800, 800 700, 700 700)" } }, { "model": "images.zone", - "pk": "ecdd78a6-c197-41fe-8a1d-857e57f31526", + "pk": "e67eba1f-4993-492e-9ca0-67451ceb094c", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "c3a900c3-7fe4-44b3-816d-ca69f8227570", - "polygon": "LINEARRING (600 600, 600 1000, 1000 1000, 1000 600, 600 600)" + "image": "c1f75796-3a1c-4e85-b8fa-43472a719312", + "polygon": "LINEARRING (0 0, 0 1000, 1000 1000, 1000 0, 0 0)" } }, { "model": "images.zone", - "pk": "f975ebab-d0e4-44f4-87fd-6c36702de2c8", + "pk": "f3b62073-8fe4-46c9-b7bf-012c3014359b", "fields": { "created": "2020-02-02T01:23:45.678Z", "updated": "2020-02-02T01:23:45.678Z", - "image": "34603613-b450-4f52-8db8-fa0410d53355", - "polygon": "LINEARRING (0 0, 0 1000, 1000 1000, 1000 0, 0 0)" + "image": "0a18ca58-69a7-44f8-b2ac-739a7a978cf2", + "polygon": "LINEARRING (300 300, 300 600, 600 600, 600 300, 300 300)" } }, { "model": "users.user", "pk": 1, "fields": { - "password": "pbkdf2_sha256$216000$qCN2CTufR3sL$0rQgDgt+QJHL2UaeY1zNT4gIljXW9NtgzdoXIkgBIVA=", + "password": "pbkdf2_sha256$216000$l8Q874FbHSd8$nuAro6QYXwWYcYcFP1hVKgZUjTYnmbAKLqvFBRpLizU=", "last_login": null, "email": "root@root.fr", "transkribus_email": null, @@ -1172,7 +1243,7 @@ "model": "users.user", "pk": 2, "fields": { - "password": "pbkdf2_sha256$216000$XCkvJTux5hQS$NbaHo9czCWEx63S979W38OyEMWn709+txXKVVl7EGp4=", + "password": "pbkdf2_sha256$216000$JbMVfYKIdmbH$HacY6ieeQBFMnMT32valEOgJnifIPuxNWx5LsaZSEN4=", "last_login": null, "email": "internal@internal.fr", "transkribus_email": null, @@ -1187,7 +1258,7 @@ "model": "users.user", "pk": 3, "fields": { - "password": "pbkdf2_sha256$216000$T6639eulurna$BjLzenXNk2tjztAJR7hfLuoHv09LwAMVTsVwJkIwPOw=", + "password": "pbkdf2_sha256$216000$RurQ9pYDub7S$bhJUTPQbo1jcqBoDS69RNbdzM6cr0ydKcE9Dk7mQyyU=", "last_login": null, "email": "user@user.fr", "transkribus_email": null, @@ -1200,7 +1271,7 @@ }, { "model": "users.oauthcredentials", - "pk": "fdd4c059-6d10-4aaa-8308-a0aa4bf20284", + "pk": "d21e40e2-32d2-4903-ac4a-6672dc6c14ba", "fields": { "user": 3, "provider_name": "gitlab", @@ -1217,7 +1288,7 @@ "pk": 1, "fields": { "user": 3, - "corpus": "2aeff5c5-69c0-4017-9104-636572f95b6f", + "corpus": "1f7e82ec-4094-4397-b729-ec424ea7a37f", "can_write": true, "can_admin": true } @@ -2805,5 +2876,48 @@ "content_type": 44, "codename": "view_dataimportelement" } +}, +{ + "model": "ponos.workflow", + "pk": "b391055a-84f5-431e-84ff-fec1836c4a5e", + "fields": { + "recipe": "tasks:\n docker_build:\n image: reco", + "created": "2020-02-02T01:23:45.678Z", + "updated": "2020-02-02T01:23:45.678Z" + } +}, +{ + "model": "ponos.task", + "pk": "71dd7910-8bef-4940-ab6a-50df883a2cb3", + "fields": { + "run": 0, + "depth": 0, + "slug": "docker_build", + "state": "completed", + "tags": "[]", + "image": "", + "command": null, + "env": null, + "has_docker_socket": false, + "image_artifact": null, + "agent": null, + "workflow": "b391055a-84f5-431e-84ff-fec1836c4a5e", + "container": null, + "created": "2020-02-02T01:23:45.678Z", + "updated": "2020-02-02T01:23:45.678Z", + "parents": [] + } +}, +{ + "model": "ponos.artifact", + "pk": "71a4b60b-a2f2-4503-8f5d-9d3c38f66626", + "fields": { + "task": "71dd7910-8bef-4940-ab6a-50df883a2cb3", + "path": "/path/to/docker_build", + "size": 42000, + "content_type": "application/octet-stream", + "created": "2020-02-02T01:23:45.678Z", + "updated": "2020-02-02T01:23:45.678Z" + } } ] diff --git a/arkindex/documents/management/commands/build_fixtures.py b/arkindex/documents/management/commands/build_fixtures.py index 08f7c16018..55d5ea4161 100644 --- a/arkindex/documents/management/commands/build_fixtures.py +++ b/arkindex/documents/management/commands/build_fixtures.py @@ -3,9 +3,10 @@ from django.core.management.base import BaseCommand from arkindex_common.ml_tool import MLToolType from arkindex_common.enums import TranscriptionType, MetaType from arkindex.documents.models import Corpus, Element, Transcription, DataSource, MetaData -from arkindex.dataimport.models import RepositoryType +from arkindex.dataimport.models import RepositoryType, WorkerVersion, WorkerVersionState, Workflow from arkindex.images.models import ImageServer, Image, Zone from arkindex.users.models import User, CorpusRight +from ponos.models import State from django.contrib.gis.geos import LinearRing from django.utils import timezone as DjangoTimeZone from unittest.mock import patch @@ -95,7 +96,7 @@ class Command(BaseCommand): token='oauth-token', ) - # Create a repository + # Create a IIIF repository repo = creds.repos.create( url='http://gitlab/repo', type=RepositoryType.IIIF, @@ -305,3 +306,47 @@ class Command(BaseCommand): sd.add_parent(act3) se.add_parent(act4) sf.add_parent(act5) + + # Create a worker repository + worker_repo = creds.repos.create( + type=RepositoryType.Worker, + url="http://my_repo.fake/workers/worker", + hook_token='worker-hook-token', + provider_name='GitLabProvider' + ) + + # Create a revision on this repository + revision = worker_repo.revisions.create( + hash="1337", + message="My w0rk3r", + author="Test user" + ) + + # Create a fake docker build with a docker image task + workflow = Workflow.objects.create(recipe='tasks:\n docker_build:\n image: reco') + build_task = workflow.tasks.create(run=0, depth=0, slug='docker_build', state=State.Completed) + docker_image = build_task.artifacts.create(size=42_000, path='/path/to/docker_build') + + # Create two workers for the repository with their available version + WorkerVersion.objects.create( + worker=worker_repo.workers.create( + name='Recognizer', + slug='reco', + type=MLToolType.Recognizer + ), + revision=revision, + configuration={'test': 42}, + state=WorkerVersionState.Available, + docker_image=docker_image + ) + WorkerVersion.objects.create( + worker=worker_repo.workers.create( + name='Document layout analyser', + slug='dla', + type=MLToolType.DLAnalyser + ), + revision=revision, + configuration={'test': 42}, + state=WorkerVersionState.Available, + docker_image=docker_image + ) diff --git a/arkindex/documents/tests/test_bulk_classification.py b/arkindex/documents/tests/test_bulk_classification.py index f1203fdd5b..a017985674 100644 --- a/arkindex/documents/tests/test_bulk_classification.py +++ b/arkindex/documents/tests/test_bulk_classification.py @@ -3,7 +3,7 @@ from arkindex_common.ml_tool import MLToolType from rest_framework import status from arkindex.project.tests import FixtureAPITestCase from arkindex.documents.models import Corpus, DataSource, MLClass -from arkindex.dataimport.models import WorkerVersion, Worker +from arkindex.dataimport.models import WorkerVersion class TestBulkClassification(FixtureAPITestCase): @@ -14,17 +14,7 @@ class TestBulkClassification(FixtureAPITestCase): cls.page = cls.corpus.elements.get(name='Volume 1, page 2r') cls.src = DataSource.objects.get(slug='test', type=MLToolType.Classifier) cls.private_corpus = Corpus.objects.create(name='private', public=False) - cls.repo = cls.user.credentials.get().repos.get() - cls.worker_version = WorkerVersion.objects.create( - worker=Worker.objects.create( - repository=cls.repo, - name='Test Worker', - slug='test_worker', - type=MLToolType.Classifier - ), - revision=cls.repo.revisions.get(), - configuration={"test": "test1"} - ) + cls.worker_version = WorkerVersion.objects.get(worker__slug='reco') @classmethod def setUpClass(cls): diff --git a/arkindex/documents/tests/test_bulk_element_transcriptions.py b/arkindex/documents/tests/test_bulk_element_transcriptions.py index cac263203b..15077ebe10 100644 --- a/arkindex/documents/tests/test_bulk_element_transcriptions.py +++ b/arkindex/documents/tests/test_bulk_element_transcriptions.py @@ -6,7 +6,7 @@ from mock import AsyncMock from rest_framework import status from arkindex.project.tests import FixtureAPITestCase from arkindex_common.enums import TranscriptionType -from arkindex.dataimport.models import Worker, WorkerVersion +from arkindex.dataimport.models import WorkerVersion from arkindex.documents.models import Element, Corpus, DataSource from arkindex_common.ml_tool import MLToolType @@ -25,9 +25,7 @@ class TestBulkElementTranscriptions(FixtureAPITestCase): cls.line = cls.corpus.elements.filter(type__slug='text_line').first() cls.private_corpus = Corpus.objects.create(name='Private') cls.private_page = cls.private_corpus.elements.create(type=cls.page.type) - cls.creds = cls.user.credentials.get() - cls.repo = cls.creds.repos.get() - cls.rev = cls.repo.revisions.get() + cls.worker_version = WorkerVersion.objects.get(worker__slug='reco') def setUp(self): self.manual_source = DataSource.objects.create(type=MLToolType.Recognizer, slug='manual', internal=False) @@ -118,17 +116,6 @@ class TestBulkElementTranscriptions(FixtureAPITestCase): self.src.internal = True self.src.save() - worker = Worker.objects.create( - repository=self.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=self.rev, - configuration={"test": "test1"} - ) transcriptions = [ ([[13, 37], [133, 37], [133, 137], [13, 137], [13, 37]], 'Hello world !', 0.1337), ([[24, 42], [64, 42], [64, 142], [24, 142], [24, 42]], 'I <3 JavaScript', 0.42), @@ -136,7 +123,7 @@ class TestBulkElementTranscriptions(FixtureAPITestCase): data = { 'element_type': 'text_line', 'transcription_type': 'line', - 'worker_version': str(version.id), + 'worker_version': str(self.worker_version.id), 'transcriptions': [{ 'polygon': poly, 'text': text, @@ -167,8 +154,8 @@ class TestBulkElementTranscriptions(FixtureAPITestCase): self.assertCountEqual( created_elts.values_list('transcriptions__type', 'transcriptions__text', 'transcriptions__zone', 'transcriptions__source', 'transcriptions__worker_version'), [ - (TranscriptionType.Line, ('Hello world !'), None, None, version.id), - (TranscriptionType.Line, ('I <3 JavaScript'), None, None, version.id) + (TranscriptionType.Line, ('Hello world !'), None, None, self.worker_version.id), + (TranscriptionType.Line, ('I <3 JavaScript'), None, None, self.worker_version.id) ] ) get_layer_mock().send.assert_called_once_with('reindex', { @@ -318,17 +305,6 @@ class TestBulkElementTranscriptions(FixtureAPITestCase): """ Transcriptions must be created with a source or a worker_version not both """ - worker = Worker.objects.create( - repository=self.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=self.rev, - configuration={"test": "test1"} - ) self.client.force_login(self.user) response = self.client.post( reverse('api:element-transcriptions-bulk', kwargs={'pk': self.page.id}), @@ -337,7 +313,7 @@ class TestBulkElementTranscriptions(FixtureAPITestCase): 'element_type': 'text_line', 'transcription_type': 'line', 'source': self.src.slug, - 'worker_version': str(version.id), + 'worker_version': str(self.worker_version.id), 'transcriptions': [{ 'polygon': [[13, 37], [133, 37], [133, 137], [13, 137]], 'text': 'Can I write womething here ?', diff --git a/arkindex/documents/tests/test_bulk_elements.py b/arkindex/documents/tests/test_bulk_elements.py index fe5d1f52d3..ba333cfb4b 100644 --- a/arkindex/documents/tests/test_bulk_elements.py +++ b/arkindex/documents/tests/test_bulk_elements.py @@ -1,8 +1,8 @@ from django.urls import reverse from rest_framework import status -from arkindex_common.ml_tool import MLToolType from arkindex.project.tests import FixtureAPITestCase from arkindex.documents.models import Element +from arkindex.dataimport.models import WorkerVersion class TestBulkElements(FixtureAPITestCase): @@ -10,17 +10,7 @@ class TestBulkElements(FixtureAPITestCase): @classmethod def setUpTestData(cls): super().setUpTestData() - repo = cls.user.credentials.get().repos.get() - worker = repo.workers.create( - name='A worker', - slug='coworker', - type=MLToolType.Recognizer, - ) - cls.worker_version = worker.workerversion_set.create( - revision=repo.revisions.get(), - configuration={}, - ) - + cls.worker_version = WorkerVersion.objects.get(worker__slug='reco') cls.payload = { 'worker_version': str(cls.worker_version.id), 'elements': [ diff --git a/arkindex/documents/tests/test_children_elements.py b/arkindex/documents/tests/test_children_elements.py index b371f143b5..2423ae9822 100644 --- a/arkindex/documents/tests/test_children_elements.py +++ b/arkindex/documents/tests/test_children_elements.py @@ -1,8 +1,7 @@ from django.urls import reverse from rest_framework import status -from arkindex_common.ml_tool import MLToolType from arkindex.documents.models import Element -from arkindex.dataimport.models import Worker, WorkerVersion +from arkindex.dataimport.models import WorkerVersion from arkindex.project.tests import FixtureAPITestCase import uuid @@ -14,6 +13,7 @@ class TestChildrenElements(FixtureAPITestCase): super().setUpTestData() cls.vol = cls.corpus.elements.get(name='Volume 1') cls.element = Element.objects.get(name='Volume 1, page 2r') + cls.worker_version = WorkerVersion.objects.get(worker__slug='dla') def test_element_children(self): response = self.client.get(reverse('api:elements-children', kwargs={'pk': str(self.element.id)})) @@ -100,23 +100,12 @@ class TestChildrenElements(FixtureAPITestCase): ]) def test_element_children_worker_version(self): - worker = Worker.objects.create( - repository=self.user.credentials.get().repos.get(), - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=worker.repository.revisions.get(), - configuration={"test": "test1"} - ) - self.corpus.elements.filter(name__contains='page 1r').update(worker_version=version) + self.corpus.elements.filter(name__contains='page 1r').update(worker_version=self.worker_version) with self.assertNumQueries(8): response = self.client.get( reverse('api:elements-children', kwargs={'pk': str(self.vol.id)}), - data={'worker_version': str(version.id)} + data={'worker_version': str(self.worker_version.id)} ) self.assertListEqual( diff --git a/arkindex/documents/tests/test_create_elements.py b/arkindex/documents/tests/test_create_elements.py index ff5ae4b51f..49eb0b0eb8 100644 --- a/arkindex/documents/tests/test_create_elements.py +++ b/arkindex/documents/tests/test_create_elements.py @@ -1,7 +1,7 @@ from django.urls import reverse from rest_framework import status from arkindex_common.ml_tool import MLToolType -from arkindex.dataimport.models import Worker, WorkerVersion +from arkindex.dataimport.models import WorkerVersion from arkindex.documents.models import \ Element, DataSource, Corpus from arkindex.images.models import ImageServer @@ -25,9 +25,7 @@ class TestCreateElements(FixtureAPITestCase): width=42, height=42, ) - cls.creds = cls.user.credentials.get() - cls.repo = cls.creds.repos.get() - cls.rev = cls.repo.revisions.get() + cls.worker_version = WorkerVersion.objects.get(worker__slug='dla') def make_create_request(self, name='default', corpus=None, elt_type='volume', **options): request = { @@ -161,21 +159,10 @@ class TestCreateElements(FixtureAPITestCase): def test_create_element_worker_version(self): # Create an element with a worker version self.client.force_login(self.user) - worker = Worker.objects.create( - repository=self.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=self.rev, - configuration={"test": "test1"} - ) request = self.make_create_request( name='Castle story', elt_type='act', - worker_version=str(version.id), + worker_version=str(self.worker_version.id), ) with self.assertNumQueries(8): response = self.client.post(**request) @@ -184,7 +171,7 @@ class TestCreateElements(FixtureAPITestCase): self.assertEqual(act.name, 'Castle story') self.assertEqual(act.type, self.act_type) self.assertEqual(act.source, None) - self.assertEqual(act.worker_version, version) + self.assertEqual(act.worker_version, self.worker_version) def test_create_element_source_and_worker_version_returns_error(self): # Create an element with a source and a worker version (not allowed) @@ -194,22 +181,11 @@ class TestCreateElements(FixtureAPITestCase): slug='fairy_tale_detector', internal=False, ) - worker = Worker.objects.create( - repository=self.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=self.rev, - configuration={"test": "test1"} - ) request = self.make_create_request( name='Castle story', elt_type='act', source='fairy_tale_detector', - worker_version=str(version.id), + worker_version=str(self.worker_version.id), ) with self.assertNumQueries(6): response = self.client.post(**request) diff --git a/arkindex/documents/tests/test_create_transcriptions.py b/arkindex/documents/tests/test_create_transcriptions.py index 71c68982ac..0be51e5152 100644 --- a/arkindex/documents/tests/test_create_transcriptions.py +++ b/arkindex/documents/tests/test_create_transcriptions.py @@ -6,7 +6,7 @@ from rest_framework import status from arkindex.project.tests import FixtureAPITestCase from arkindex_common.enums import TranscriptionType from arkindex_common.ml_tool import MLToolType -from arkindex.dataimport.models import Worker, WorkerVersion +from arkindex.dataimport.models import WorkerVersion from arkindex.documents.models import Corpus, Transcription, DataSource from arkindex.users.models import User from uuid import uuid4 @@ -30,9 +30,7 @@ class TestTranscriptionCreate(FixtureAPITestCase): cls.private_read_user.verified_email = True cls.private_read_user.save() cls.private_corpus.corpus_right.create(user=cls.private_read_user) - cls.creds = cls.user.credentials.get() - cls.repo = cls.creds.repos.get() - cls.rev = cls.repo.revisions.get() + cls.worker_version = WorkerVersion.objects.get(worker__slug='reco') def setUp(self): self.manual_source = DataSource.objects.create(type=MLToolType.Recognizer, slug='manual', internal=False) @@ -251,17 +249,6 @@ class TestTranscriptionCreate(FixtureAPITestCase): def test_create_transcription_source_and_worker_version_returns_error(self): self.client.force_login(self.user) - worker = Worker.objects.create( - repository=self.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=self.rev, - configuration={"test": "test1"} - ) response = self.client.post( reverse('api:transcription-create', kwargs={'pk': self.line.id}), format='json', @@ -269,7 +256,7 @@ class TestTranscriptionCreate(FixtureAPITestCase): 'type': 'word', 'text': 'NEKUDOTAYIM', 'source': 'manual', - 'worker_version': str(version.id), + 'worker_version': str(self.worker_version.id), } ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) @@ -280,30 +267,22 @@ class TestTranscriptionCreate(FixtureAPITestCase): def test_create_transcription_worker_version_non_internal(self): self.client.force_login(self.user) - worker = Worker.objects.create( - repository=self.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=self.rev, - configuration={"test": "test1"} - ) response = self.client.post( reverse('api:transcription-create', kwargs={'pk': self.line.id}), format='json', data={ 'type': 'word', 'text': 'NEKUDOTAYIM', - 'worker_version': str(version.id), + 'worker_version': str(self.worker_version.id), 'score': .42 } ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertDictEqual(response.json(), { - 'worker_version': [f'An internal user is required to create a transcription with the worker_version "{version.id}"'] + 'worker_version': [( + 'An internal user is required to create a transcription ' + f'with the worker_version "{self.worker_version.id}"' + )] }) @patch('arkindex.project.triggers.get_channel_layer') @@ -311,37 +290,26 @@ class TestTranscriptionCreate(FixtureAPITestCase): get_layer_mock.return_value.send = AsyncMock() self.client.force_login(self.internal_user) - worker = Worker.objects.create( - repository=self.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=self.rev, - configuration={"test": "test1"} - ) response = self.client.post( reverse('api:transcription-create', kwargs={'pk': self.line.id}), format='json', data={ 'type': 'word', 'text': 'NEKUDOTAYIM', - 'worker_version': str(version.id), + 'worker_version': str(self.worker_version.id), 'score': .42 } ) self.assertEqual(response.status_code, status.HTTP_201_CREATED) tr = Transcription.objects.get(text='NEKUDOTAYIM') - self.assertEqual(tr.worker_version, version) + self.assertEqual(tr.worker_version, self.worker_version) self.assertDictEqual(response.json(), { 'id': str(tr.id), 'score': .42, 'source': None, 'text': 'NEKUDOTAYIM', 'type': 'word', - 'worker_version_id': str(version.id), + 'worker_version_id': str(self.worker_version.id), 'zone': None }) diff --git a/arkindex/documents/tests/test_entities_api.py b/arkindex/documents/tests/test_entities_api.py index c1211ea728..5b1645f530 100644 --- a/arkindex/documents/tests/test_entities_api.py +++ b/arkindex/documents/tests/test_entities_api.py @@ -4,7 +4,7 @@ from unittest.mock import Mock, patch, call from rest_framework import status from arkindex_common.enums import MetaType from arkindex.project.tests import FixtureAPITestCase -from arkindex.dataimport.models import Worker, WorkerVersion +from arkindex.dataimport.models import WorkerVersion from django.contrib.gis.geos import LinearRing from arkindex.documents.models import ( Corpus, Element, TranscriptionType, DataSource, MLToolType, @@ -29,9 +29,7 @@ class TestEntitiesAPI(FixtureAPITestCase): ) cls.source = DataSource.objects.get(slug='test', type=MLToolType.Recognizer) cls.private_corpus = Corpus.objects.create(name='private') - cls.creds = cls.user.credentials.get() - cls.repo = cls.creds.repos.get() - cls.rev = cls.repo.revisions.get() + cls.worker_version = WorkerVersion.objects.get(worker__slug='reco') def setUp(self): super().setUp() @@ -325,17 +323,6 @@ class TestEntitiesAPI(FixtureAPITestCase): }) def test_create_entity_with_source_and_worker_version_returns_error(self): - worker = Worker.objects.create( - repository=self.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=self.rev, - configuration={"test": "test1"} - ) data = { 'name': '1789', 'type': EntityType.Date.value, @@ -345,7 +332,7 @@ class TestEntitiesAPI(FixtureAPITestCase): 'other key': 'other value' }, 'ner': self.entity_source.slug, - 'worker_version': str(version.id) + 'worker_version': str(self.worker_version.id) } self.client.force_login(self.user) response = self.client.post(reverse('api:entity-create'), data=data, format='json') @@ -356,17 +343,6 @@ class TestEntitiesAPI(FixtureAPITestCase): }) def test_create_entity_with_worker_version(self): - worker = Worker.objects.create( - repository=self.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=self.rev, - configuration={"test": "test1"} - ) data = { 'name': '1789', 'type': EntityType.Date.value, @@ -375,7 +351,7 @@ class TestEntitiesAPI(FixtureAPITestCase): 'key': 'value', 'other key': 'other value' }, - 'worker_version': str(version.id) + 'worker_version': str(self.worker_version.id) } self.client.force_login(self.user) response = self.client.post(reverse('api:entity-create'), data=data, format='json') @@ -383,7 +359,7 @@ class TestEntitiesAPI(FixtureAPITestCase): entity = Entity.objects.get(id=response.json()['id']) self.assertEqual(entity.name, '1789') self.assertEqual(entity.source, None) - self.assertEqual(entity.worker_version, version) + self.assertEqual(entity.worker_version, self.worker_version) def test_create_link(self): child = Entity.objects.create( @@ -579,19 +555,8 @@ class TestEntitiesAPI(FixtureAPITestCase): ) def test_list_transcription_entities_worker_version(self): - worker = Worker.objects.create( - repository=self.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=self.rev, - configuration={"test": "test1"} - ) self.entity_bis.source = None - self.entity_bis.worker_version = version + self.entity_bis.worker_version = self.worker_version self.entity_bis.save() response = self.client.get(reverse('api:transcription-entities', kwargs={'pk': str(self.transcription.id)})) @@ -607,7 +572,7 @@ class TestEntitiesAPI(FixtureAPITestCase): 'validated': False, 'dates': [], 'source': None, - 'worker_version_id': str(version.id), + 'worker_version_id': str(self.worker_version.id), }, 'length': 8, 'offset': 2 @@ -715,25 +680,14 @@ class TestEntitiesAPI(FixtureAPITestCase): self.assertEqual(response.json(), {'worker_version': ['This worker version does not exist.']}) def test_list_element_entities_worker_version(self): - worker = Worker.objects.create( - repository=self.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=self.rev, - configuration={"test": "test1"} - ) self.entity.source = None - self.entity.worker_version = version + self.entity.worker_version = self.worker_version self.entity.save() with self.assertNumQueries(6): response = self.client.get( reverse('api:element-entities', kwargs={'pk': str(self.page.id)}), - data={'worker_version': str(version.id)} + data={'worker_version': str(self.worker_version.id)} ) self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -760,7 +714,7 @@ class TestEntitiesAPI(FixtureAPITestCase): 'dates': [], 'metas': None, 'source': None, - 'worker_version_id': str(version.id), + 'worker_version_id': str(self.worker_version.id), }, } ], diff --git a/arkindex/documents/tests/test_list_elements.py b/arkindex/documents/tests/test_list_elements.py index 84eedef388..25e6b53f19 100644 --- a/arkindex/documents/tests/test_list_elements.py +++ b/arkindex/documents/tests/test_list_elements.py @@ -1,15 +1,19 @@ from django.urls import reverse from django.db.models.sql.constants import LOUTER from rest_framework import status -from arkindex_common.ml_tool import MLToolType from arkindex.documents.models import Corpus -from arkindex.dataimport.models import Worker, WorkerVersion +from arkindex.dataimport.models import WorkerVersion from arkindex.project.tests import FixtureAPITestCase import uuid class TestListElements(FixtureAPITestCase): + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.worker_version = WorkerVersion.objects.get(worker__slug='reco') + def test_list_elements_filter_name(self): nameSelected = 'ol' with self.assertNumQueries(7): @@ -114,23 +118,12 @@ class TestListElements(FixtureAPITestCase): ) def test_list_elements_filter_worker_version(self): - worker = Worker.objects.create( - repository=self.user.credentials.get().repos.get(), - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=worker.repository.revisions.get(), - configuration={"test": "test1"} - ) - self.corpus.elements.filter(name__contains='Volume 2').update(worker_version=version) + self.corpus.elements.filter(name__contains='Volume 2').update(worker_version=self.worker_version) with self.assertNumQueries(9): response = self.client.get( reverse('api:elements'), - data={'corpus': self.corpus.id, 'worker_version': str(version.id)}, + data={'corpus': self.corpus.id, 'worker_version': str(self.worker_version.id)}, ) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertListEqual( diff --git a/arkindex/documents/tests/test_moderation.py b/arkindex/documents/tests/test_moderation.py index f38b9831d7..58aa646b76 100644 --- a/arkindex/documents/tests/test_moderation.py +++ b/arkindex/documents/tests/test_moderation.py @@ -2,7 +2,7 @@ from django.test import override_settings from django.urls import reverse from rest_framework import status -from arkindex.dataimport.models import Worker, WorkerVersion +from arkindex.dataimport.models import WorkerVersion from arkindex.documents.models import \ ClassificationState, DataSource, MLClass, Element, Corpus, Classification, MLToolType from arkindex.project.tests import FixtureAPITestCase @@ -26,9 +26,7 @@ class TestClasses(FixtureAPITestCase): revision='1.3.3.7', internal=False, ) - cls.creds = cls.user.credentials.get() - cls.repo = cls.creds.repos.get() - cls.rev = cls.repo.revisions.get() + cls.worker_version = WorkerVersion.objects.get(worker__slug='dla') cls.internal_user = User.objects.get_by_natural_key('internal@internal.fr') def _create_classification(self): @@ -148,23 +146,12 @@ class TestClasses(FixtureAPITestCase): }) def test_classification_creation_source_and_worker_version_returns_error(self): - worker = Worker.objects.create( - repository=self.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=self.rev, - configuration={"test": "test1"} - ) self.client.force_login(self.user) response = self.client.post(reverse('api:classification-create'), { 'element': str(self.element.id), 'ml_class': str(self.text.id), 'source': 'manual', - 'worker_version': str(version.id), + 'worker_version': str(self.worker_version.id), 'confidence': 0.42, 'high_confidence': False, }) @@ -215,56 +202,35 @@ class TestClasses(FixtureAPITestCase): """ Test creating a classification on a worker_version requires an internal user """ - worker = Worker.objects.create( - repository=self.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=self.rev, - configuration={"test": "test1"} - ) self.client.force_login(self.user) response = self.client.post(reverse('api:classification-create'), { 'element': str(self.element.id), 'ml_class': str(self.text.id), - 'worker_version': str(version.id), + 'worker_version': str(self.worker_version.id), }) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertDictEqual(response.json(), { - 'worker_version': [ - f'An internal user is required to create a classification with the worker_version "{version.id}"' - ], + 'worker_version': [( + 'An internal user is required to create a classification ' + f'with the worker_version "{self.worker_version.id}"' + )], 'confidence': ['This field is required for non manual sources.'], 'high_confidence': ['This field is required for non manual sources.'], }) def test_classification_creation_worker_version(self): - worker = Worker.objects.create( - repository=self.repo, - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=self.rev, - configuration={"test": "test1"} - ) self.client.force_login(self.internal_user) response = self.client.post(reverse('api:classification-create'), { 'element': str(self.element.id), 'ml_class': str(self.text.id), - 'worker_version': str(version.id), + 'worker_version': str(self.worker_version.id), 'confidence': 0.42, 'high_confidence': False, }) self.assertEqual(response.status_code, status.HTTP_201_CREATED) classification = self.element.classifications.get() self.assertEqual(classification.source, None) - self.assertEqual(classification.worker_version, version) + self.assertEqual(classification.worker_version, self.worker_version) self.assertEqual(classification.ml_class, self.text) self.assertEqual(classification.state, ClassificationState.Pending) self.assertEqual(classification.confidence, 0.42) diff --git a/arkindex/documents/tests/test_parents_elements.py b/arkindex/documents/tests/test_parents_elements.py index dcace96a97..b3f3a5e5b5 100644 --- a/arkindex/documents/tests/test_parents_elements.py +++ b/arkindex/documents/tests/test_parents_elements.py @@ -2,7 +2,7 @@ from django.urls import reverse from rest_framework import status from arkindex_common.ml_tool import MLToolType from arkindex.documents.models import Element, DataSource, Corpus -from arkindex.dataimport.models import Worker, WorkerVersion +from arkindex.dataimport.models import WorkerVersion from arkindex.project.tests import FixtureAPITestCase import uuid @@ -16,6 +16,7 @@ class TestParentsElements(FixtureAPITestCase): cls.private_corpus = Corpus.objects.create(name='private', public=False) cls.private_elt = cls.private_corpus.elements.create(type=cls.private_corpus.types.create(slug='type')) cls.manual_source = DataSource.objects.create(type=MLToolType.Recognizer, slug='manual', internal=True) + cls.worker_version = WorkerVersion.objects.get(worker__slug='reco') def setUp(self): self.page = self.corpus.elements.get(name='Volume 1, page 1r') @@ -68,23 +69,15 @@ class TestParentsElements(FixtureAPITestCase): self.assertEqual(response.json()['results'][0]['name'], 'Act 1') def test_parents_worker_version(self): - worker = Worker.objects.create( - repository=self.user.credentials.get().repos.get(), - name='Worker 1', - slug='worker_1', - type=MLToolType.Classifier - ) - version = WorkerVersion.objects.create( - worker=worker, - revision=worker.repository.revisions.get(), - configuration={"test": "test1"} - ) - self.corpus.elements.filter(name__contains='Volume 1').update(worker_version=version) + """ + List parents filtered by worker_version + """ + self.corpus.elements.filter(name__contains='Volume 1').update(worker_version=self.worker_version) with self.assertNumQueries(6): response = self.client.get( reverse('api:elements-parents', kwargs={'pk': str(self.page.id)}), - data={'worker_version': str(version.id)}, + data={'worker_version': str(self.worker_version.id)}, ) self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/arkindex/documents/tests/test_transcriptions.py b/arkindex/documents/tests/test_transcriptions.py index a32205df96..2024377959 100644 --- a/arkindex/documents/tests/test_transcriptions.py +++ b/arkindex/documents/tests/test_transcriptions.py @@ -5,7 +5,7 @@ from django.contrib.gis.geos import LinearRing from arkindex_common.enums import TranscriptionType from arkindex_common.ml_tool import MLToolType from arkindex.documents.models import Corpus, DataSource -from arkindex.dataimport.models import Worker, WorkerVersion +from arkindex.dataimport.models import WorkerVersion from arkindex.users.models import User @@ -27,17 +27,7 @@ class TestTranscriptions(FixtureAPITestCase): cls.private_read_user = User.objects.create_user('a@bc.de', 'a') cls.private_read_user.verified_email = True cls.private_read_user.save() - cls.repo = cls.user.credentials.get().repos.get() - cls.worker_version = WorkerVersion.objects.create( - worker=Worker.objects.create( - repository=cls.repo, - name='Test Worker', - slug='test_worker', - type=MLToolType.Classifier - ), - revision=cls.repo.revisions.get(), - configuration={"test": "test1"} - ) + cls.worker_version = WorkerVersion.objects.get(worker__slug='reco') def test_list_transcriptions_read_right(self): # A read right on the element corpus is required to access transcriptions diff --git a/arkindex/users/tests/test_gitlab_oauth.py b/arkindex/users/tests/test_gitlab_oauth.py index 896a12c24e..04805eb8be 100644 --- a/arkindex/users/tests/test_gitlab_oauth.py +++ b/arkindex/users/tests/test_gitlab_oauth.py @@ -143,6 +143,8 @@ class TestGitLabOAuthProvider(FixtureTestCase): GitLabOAuthProvider(request=request_mock, credentials=self.creds).disconnect() - self.assertEqual(self.gl_mock().projects.get.call_count, 1) - self.assertEqual(self.gl_mock().projects.get.return_value.hooks.list.call_count, 1) - self.assertEqual(hook_mock.delete.call_count, 1) + # Number of repositories associated to those credentials + repos_count = self.creds.repos.count() + self.assertEqual(self.gl_mock().projects.get.call_count, repos_count) + self.assertEqual(self.gl_mock().projects.get.return_value.hooks.list.call_count, repos_count) + self.assertEqual(hook_mock.delete.call_count, repos_count) -- GitLab