udata 10.8.2.dev36872__py2.py3-none-any.whl → 10.8.2.dev36938__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of udata might be problematic. Click here for more details.

Files changed (34) hide show
  1. udata/harvest/actions.py +24 -28
  2. udata/harvest/api.py +25 -33
  3. udata/harvest/commands.py +7 -7
  4. udata/harvest/tasks.py +1 -1
  5. udata/harvest/tests/ckan/test_ckan_backend.py +5 -5
  6. udata/harvest/tests/ckan/test_ckan_backend_errors.py +6 -6
  7. udata/harvest/tests/ckan/test_ckan_backend_filters.py +5 -5
  8. udata/harvest/tests/ckan/test_dkan_backend.py +1 -1
  9. udata/harvest/tests/test_actions.py +27 -32
  10. udata/harvest/tests/test_api.py +23 -18
  11. udata/harvest/tests/test_dcat_backend.py +29 -29
  12. udata/routing.py +6 -0
  13. udata/static/chunks/{11.55ab79044cda0271b595.js → 11.822f6ccb39c92c796d13.js} +3 -3
  14. udata/static/chunks/{11.55ab79044cda0271b595.js.map → 11.822f6ccb39c92c796d13.js.map} +1 -1
  15. udata/static/chunks/{13.2d06442dd9a05d9777b5.js → 13.d9c1735d14038b94c17e.js} +2 -2
  16. udata/static/chunks/{13.2d06442dd9a05d9777b5.js.map → 13.d9c1735d14038b94c17e.js.map} +1 -1
  17. udata/static/chunks/{17.e8e4caaad5cb0cc0bacc.js → 17.81c57c0dedf812e43013.js} +2 -2
  18. udata/static/chunks/{17.e8e4caaad5cb0cc0bacc.js.map → 17.81c57c0dedf812e43013.js.map} +1 -1
  19. udata/static/chunks/{19.f03a102365af4315f9db.js → 19.8d03c06efcac6884bebe.js} +3 -3
  20. udata/static/chunks/{19.f03a102365af4315f9db.js.map → 19.8d03c06efcac6884bebe.js.map} +1 -1
  21. udata/static/chunks/{5.5660483641193b7f8295.js → 5.343ca020a2d38cec1a14.js} +3 -3
  22. udata/static/chunks/{5.5660483641193b7f8295.js.map → 5.343ca020a2d38cec1a14.js.map} +1 -1
  23. udata/static/chunks/{6.30dce49d17db07600b06.js → 6.a3b07de9dd2ca2d24e85.js} +3 -3
  24. udata/static/chunks/{6.30dce49d17db07600b06.js.map → 6.a3b07de9dd2ca2d24e85.js.map} +1 -1
  25. udata/static/chunks/{8.b58fcd977fcaf3415571.js → 8.462bb3029de008497675.js} +2 -2
  26. udata/static/chunks/{8.b58fcd977fcaf3415571.js.map → 8.462bb3029de008497675.js.map} +1 -1
  27. udata/static/common.js +1 -1
  28. udata/static/common.js.map +1 -1
  29. {udata-10.8.2.dev36872.dist-info → udata-10.8.2.dev36938.dist-info}/METADATA +2 -1
  30. {udata-10.8.2.dev36872.dist-info → udata-10.8.2.dev36938.dist-info}/RECORD +34 -34
  31. {udata-10.8.2.dev36872.dist-info → udata-10.8.2.dev36938.dist-info}/LICENSE +0 -0
  32. {udata-10.8.2.dev36872.dist-info → udata-10.8.2.dev36938.dist-info}/WHEEL +0 -0
  33. {udata-10.8.2.dev36872.dist-info → udata-10.8.2.dev36938.dist-info}/entry_points.txt +0 -0
  34. {udata-10.8.2.dev36872.dist-info → udata-10.8.2.dev36938.dist-info}/top_level.txt +0 -0
udata/harvest/actions.py CHANGED
@@ -29,6 +29,11 @@ log = logging.getLogger(__name__)
29
29
  DEFAULT_PAGE_SIZE = 10
30
30
 
31
31
 
32
+ def get_source(ident):
33
+ """Get an harvest source given its ID or its slug"""
34
+ return HarvestSource.get(ident)
35
+
36
+
32
37
  def list_backends():
33
38
  """List all available backends"""
34
39
  return backends.get_all(current_app).values()
@@ -44,11 +49,6 @@ def list_sources(owner=None, deleted=False):
44
49
  return list(sources)
45
50
 
46
51
 
47
- def get_source(ident):
48
- """Get an harvest source given its ID or its slug"""
49
- return HarvestSource.get(ident)
50
-
51
-
52
52
  def get_job(ident):
53
53
  """Get an harvest job given its ID"""
54
54
  return HarvestJob.objects.get(id=ident)
@@ -89,31 +89,28 @@ def create_source(
89
89
  return source
90
90
 
91
91
 
92
- def update_source(ident, data):
92
+ def update_source(source: HarvestSource, data):
93
93
  """Update an harvest source"""
94
- source = get_source(ident)
95
94
  source.modify(**data)
96
95
  signals.harvest_source_updated.send(source)
97
96
  return source
98
97
 
99
98
 
100
- def validate_source(ident, comment=None):
99
+ def validate_source(source: HarvestSource, comment=None):
101
100
  """Validate a source for automatic harvesting"""
102
- source = get_source(ident)
103
101
  source.validation.on = datetime.utcnow()
104
102
  source.validation.comment = comment
105
103
  source.validation.state = VALIDATION_ACCEPTED
106
104
  if current_user.is_authenticated:
107
105
  source.validation.by = current_user._get_current_object()
108
106
  source.save()
109
- schedule(ident, cron=current_app.config["HARVEST_DEFAULT_SCHEDULE"])
110
- launch(ident)
107
+ schedule(source, cron=current_app.config["HARVEST_DEFAULT_SCHEDULE"])
108
+ launch(source)
111
109
  return source
112
110
 
113
111
 
114
- def reject_source(ident, comment):
112
+ def reject_source(source: HarvestSource, comment):
115
113
  """Reject a source for automatic harvesting"""
116
- source = get_source(ident)
117
114
  source.validation.on = datetime.utcnow()
118
115
  source.validation.comment = comment
119
116
  source.validation.state = VALIDATION_REFUSED
@@ -123,18 +120,16 @@ def reject_source(ident, comment):
123
120
  return source
124
121
 
125
122
 
126
- def delete_source(ident):
123
+ def delete_source(source: HarvestSource):
127
124
  """Delete an harvest source"""
128
- source = get_source(ident)
129
125
  source.deleted = datetime.utcnow()
130
126
  source.save()
131
127
  signals.harvest_source_deleted.send(source)
132
128
  return source
133
129
 
134
130
 
135
- def clean_source(ident):
131
+ def clean_source(source: HarvestSource):
136
132
  """Deletes all datasets linked to a harvest source"""
137
- source = get_source(ident)
138
133
  datasets = Dataset.objects.filter(harvest__source_id=str(source.id))
139
134
  for dataset in datasets:
140
135
  dataset.deleted = datetime.utcnow()
@@ -180,22 +175,20 @@ def purge_jobs():
180
175
  return HarvestJob.objects(created__lt=expiration).delete()
181
176
 
182
177
 
183
- def run(ident):
178
+ def run(source: HarvestSource):
184
179
  """Launch or resume an harvesting for a given source if none is running"""
185
- source = get_source(ident)
186
180
  cls = backends.get(current_app, source.backend)
187
181
  backend = cls(source)
188
182
  backend.harvest()
189
183
 
190
184
 
191
- def launch(ident):
185
+ def launch(source: HarvestSource):
192
186
  """Launch or resume an harvesting for a given source if none is running"""
193
- return harvest.delay(ident)
187
+ return harvest.delay(source.id)
194
188
 
195
189
 
196
- def preview(ident):
190
+ def preview(source: HarvestSource):
197
191
  """Preview an harvesting for a given source"""
198
- source = get_source(ident)
199
192
  cls = backends.get(current_app, source.backend)
200
193
  max_items = current_app.config["HARVEST_PREVIEW_MAX_ITEMS"]
201
194
  backend = cls(source, dryrun=True, max_items=max_items)
@@ -240,11 +233,15 @@ def preview_from_config(
240
233
 
241
234
 
242
235
  def schedule(
243
- ident, cron=None, minute="*", hour="*", day_of_week="*", day_of_month="*", month_of_year="*"
236
+ source: HarvestSource,
237
+ cron=None,
238
+ minute="*",
239
+ hour="*",
240
+ day_of_week="*",
241
+ day_of_month="*",
242
+ month_of_year="*",
244
243
  ):
245
244
  """Schedule an harvesting on a source given a crontab"""
246
- source = get_source(ident)
247
-
248
245
  if cron:
249
246
  minute, hour, day_of_month, month_of_year, day_of_week = cron.split()
250
247
 
@@ -273,9 +270,8 @@ def schedule(
273
270
  return source
274
271
 
275
272
 
276
- def unschedule(ident):
273
+ def unschedule(source: HarvestSource):
277
274
  """Unschedule an harvesting on a source"""
278
- source = get_source(ident)
279
275
  if not source.periodic_task:
280
276
  msg = "Harvesting on source {0} is ot scheduled".format(source.name)
281
277
  raise ValueError(msg)
udata/harvest/api.py CHANGED
@@ -300,59 +300,54 @@ class SourcesAPI(API):
300
300
  return source, 201
301
301
 
302
302
 
303
- @ns.route("/source/<string:ident>/", endpoint="harvest_source")
304
- @api.param("ident", "A source ID or slug")
303
+ @ns.route("/source/<harvest_source:source>/", endpoint="harvest_source")
305
304
  class SourceAPI(API):
306
305
  @api.doc("get_harvest_source")
307
306
  @api.marshal_with(source_fields)
308
- def get(self, ident):
307
+ def get(self, source: HarvestSource):
309
308
  """Get a single source given an ID or a slug"""
310
- return actions.get_source(ident)
309
+ return source
311
310
 
312
311
  @api.secure
313
312
  @api.doc("update_harvest_source")
314
313
  @api.expect(source_fields)
315
314
  @api.marshal_with(source_fields)
316
- def put(self, ident):
315
+ def put(self, source: HarvestSource):
317
316
  """Update a harvest source"""
318
- source = actions.get_source(ident)
319
317
  OwnablePermission(source).test()
320
318
  form = api.validate(HarvestSourceForm, source)
321
- source = actions.update_source(ident, form.data)
319
+ source = actions.update_source(source, form.data)
322
320
  return source
323
321
 
324
322
  @api.secure
325
323
  @api.doc("delete_harvest_source")
326
324
  @api.marshal_with(source_fields)
327
- def delete(self, ident):
328
- source: HarvestSource = actions.get_source(ident)
325
+ def delete(self, source: HarvestSource):
329
326
  OwnablePermission(source).test()
330
- return actions.delete_source(ident), 204
327
+ return actions.delete_source(source), 204
331
328
 
332
329
 
333
- @ns.route("/source/<string:ident>/validate/", endpoint="validate_harvest_source")
334
- @api.param("ident", "A source ID or slug")
330
+ @ns.route("/source/<harvest_source:source>/validate/", endpoint="validate_harvest_source")
335
331
  class ValidateSourceAPI(API):
336
332
  @api.doc("validate_harvest_source")
337
333
  @api.secure(admin_permission)
338
334
  @api.expect(validation_fields)
339
335
  @api.marshal_with(source_fields)
340
- def post(self, ident):
336
+ def post(self, source: HarvestSource):
341
337
  """Validate or reject an harvest source"""
342
338
  form = api.validate(HarvestSourceValidationForm)
343
339
  if form.state.data == VALIDATION_ACCEPTED:
344
- return actions.validate_source(ident, form.comment.data)
340
+ return actions.validate_source(source, form.comment.data)
345
341
  else:
346
- return actions.reject_source(ident, form.comment.data)
342
+ return actions.reject_source(source, form.comment.data)
347
343
 
348
344
 
349
- @ns.route("/source/<string:ident>/run/", endpoint="run_harvest_source")
350
- @api.param("ident", "A source ID or slug")
345
+ @ns.route("/source/<harvest_source:source>/run/", endpoint="run_harvest_source")
351
346
  class RunSourceAPI(API):
352
347
  @api.doc("run_harvest_source")
353
348
  @api.secure
354
349
  @api.marshal_with(source_fields)
355
- def post(self, ident):
350
+ def post(self, source: HarvestSource):
356
351
  enabled = current_app.config.get("HARVEST_ENABLE_MANUAL_RUN")
357
352
  if not enabled and not current_user.sysadmin:
358
353
  api.abort(
@@ -360,39 +355,37 @@ class RunSourceAPI(API):
360
355
  "Cannot run source manually. Please contact the platform if you need to reschedule the harvester.",
361
356
  )
362
357
 
363
- source: HarvestSource = actions.get_source(ident)
364
358
  OwnablePermission(source).test()
365
359
 
366
360
  if source.validation.state != VALIDATION_ACCEPTED:
367
361
  api.abort(400, "Source is not validated. Please validate the source before running.")
368
362
 
369
- actions.launch(ident)
363
+ actions.launch(source)
370
364
 
371
365
  return source
372
366
 
373
367
 
374
- @ns.route("/source/<string:ident>/schedule/", endpoint="schedule_harvest_source")
375
- @api.param("ident", "A source ID or slug")
368
+ @ns.route("/source/<harvest_source:source>/schedule/", endpoint="schedule_harvest_source")
376
369
  class ScheduleSourceAPI(API):
377
370
  @api.doc("schedule_harvest_source")
378
371
  @api.secure(admin_permission)
379
372
  @api.expect((str, "A cron expression"))
380
373
  @api.marshal_with(source_fields)
381
- def post(self, ident):
374
+ def post(self, source: HarvestSource):
382
375
  """Schedule an harvest source"""
383
376
  # Handle both syntax: quoted and unquoted
384
377
  try:
385
378
  data = request.json
386
379
  except BadRequest:
387
380
  data = request.data.decode("utf-8")
388
- return actions.schedule(ident, data)
381
+ return actions.schedule(source, data)
389
382
 
390
383
  @api.doc("unschedule_harvest_source")
391
384
  @api.secure(admin_permission)
392
385
  @api.marshal_with(source_fields)
393
- def delete(self, ident):
386
+ def delete(self, source: HarvestSource):
394
387
  """Unschedule an harvest source"""
395
- return actions.unschedule(ident), 204
388
+ return actions.unschedule(source), 204
396
389
 
397
390
 
398
391
  @ns.route("/source/preview/", endpoint="preview_harvest_source_config")
@@ -409,15 +402,14 @@ class PreviewSourceConfigAPI(API):
409
402
  return actions.preview_from_config(**form.data)
410
403
 
411
404
 
412
- @ns.route("/source/<string:ident>/preview/", endpoint="preview_harvest_source")
413
- @api.param("ident", "A source ID or slug")
405
+ @ns.route("/source/<harvest_source:source>/preview/", endpoint="preview_harvest_source")
414
406
  class PreviewSourceAPI(API):
415
407
  @api.secure
416
408
  @api.doc("preview_harvest_source")
417
409
  @api.marshal_with(preview_job_fields)
418
- def get(self, ident):
410
+ def get(self, source: HarvestSource):
419
411
  """Preview a single harvest source given an ID or a slug"""
420
- return actions.preview(ident)
412
+ return actions.preview(source)
421
413
 
422
414
 
423
415
  parser = api.parser()
@@ -427,15 +419,15 @@ parser.add_argument(
427
419
  )
428
420
 
429
421
 
430
- @ns.route("/source/<string:ident>/jobs/", endpoint="harvest_jobs")
422
+ @ns.route("/source/<harvest_source:source>/jobs/", endpoint="harvest_jobs")
431
423
  class JobsAPI(API):
432
424
  @api.doc("list_harvest_jobs")
433
425
  @api.expect(parser)
434
426
  @api.marshal_with(job_page_fields)
435
- def get(self, ident):
427
+ def get(self, source: HarvestSource):
436
428
  """List all jobs for a given source"""
437
429
  args = parser.parse_args()
438
- qs = HarvestJob.objects(source=ident)
430
+ qs = HarvestJob.objects(source=source)
439
431
  qs = qs.order_by("-created")
440
432
  return qs.paginate(args["page"], args["page_size"])
441
433
 
udata/harvest/commands.py CHANGED
@@ -44,7 +44,7 @@ def create(name, url, backend, frequency=None, owner=None, org=None):
44
44
  @click.argument("identifier")
45
45
  def validate(identifier):
46
46
  """Validate a source given its identifier"""
47
- source = actions.validate_source(identifier)
47
+ source = actions.validate_source(actions.get_source(identifier))
48
48
  log.info("Source %s (%s) has been validated", source.slug, str(source.id))
49
49
 
50
50
 
@@ -52,7 +52,7 @@ def validate(identifier):
52
52
  def delete(identifier):
53
53
  """Delete a harvest source"""
54
54
  log.info('Deleting source "%s"', identifier)
55
- actions.delete_source(identifier)
55
+ actions.delete_source(actions.get_source(identifier))
56
56
  log.info('Deleted source "%s"', identifier)
57
57
 
58
58
 
@@ -61,7 +61,7 @@ def delete(identifier):
61
61
  def clean(identifier):
62
62
  """Delete all datasets linked to a harvest source"""
63
63
  log.info(f'Cleaning source "{identifier}"')
64
- num_of_datasets = actions.clean_source(identifier)
64
+ num_of_datasets = actions.clean_source(actions.get_source(identifier))
65
65
  log.info(f'Cleaned source "{identifier}" - deleted {num_of_datasets} dataset(s)')
66
66
 
67
67
 
@@ -99,7 +99,7 @@ def backends():
99
99
  def launch(identifier):
100
100
  """Launch a source harvesting on the workers"""
101
101
  log.info('Launching harvest job for source "%s"', identifier)
102
- actions.launch(identifier)
102
+ actions.launch(actions.get_source(identifier))
103
103
 
104
104
 
105
105
  @grp.command()
@@ -107,7 +107,7 @@ def launch(identifier):
107
107
  def run(identifier):
108
108
  """Run a harvester synchronously"""
109
109
  log.info('Harvesting source "%s"', identifier)
110
- actions.run(identifier)
110
+ actions.run(actions.get_source(identifier))
111
111
 
112
112
 
113
113
  @grp.command()
@@ -121,7 +121,7 @@ def run(identifier):
121
121
  @click.option("-M", "--month-of-year", default="*", help="The crontab expression for month of year")
122
122
  def schedule(identifier, **kwargs):
123
123
  """Schedule a harvest job to run periodically"""
124
- source = actions.schedule(identifier, **kwargs)
124
+ source = actions.schedule(actions.get_source(identifier), **kwargs)
125
125
  msg = "Scheduled {source.name} with the following crontab: {cron}"
126
126
  log.info(msg.format(source=source, cron=source.periodic_task.crontab))
127
127
 
@@ -130,7 +130,7 @@ def schedule(identifier, **kwargs):
130
130
  @click.argument("identifier")
131
131
  def unschedule(identifier):
132
132
  """Unschedule a periodical harvest job"""
133
- source = actions.unschedule(identifier)
133
+ source = actions.unschedule(actions.get_source(identifier))
134
134
  log.info('Unscheduled harvest source "%s"', source.name)
135
135
 
136
136
 
udata/harvest/tasks.py CHANGED
@@ -14,7 +14,7 @@ def harvest(self, ident):
14
14
 
15
15
  source = HarvestSource.get(ident)
16
16
  if source.deleted or not source.active:
17
- log.info('Ignoring inactive or deleted source "%s"', ident)
17
+ log.info('Ignoring inactive or deleted source "%s"', source.id)
18
18
  return # Ignore deleted and inactive sources
19
19
  Backend = backends.get(current_app, source.backend)
20
20
  backend = Backend(source)
@@ -96,7 +96,7 @@ def harvest_ckan(request, source, ckan, app, rmock):
96
96
  )
97
97
 
98
98
  with app.app_context():
99
- actions.run(source.slug)
99
+ actions.run(source)
100
100
  source.reload()
101
101
  job = source.get_last_job()
102
102
  assert len(job.items) == 1
@@ -565,7 +565,7 @@ def test_minimal_ckan_response(app, rmock):
565
565
  status_code=200,
566
566
  headers={"Content-Type": "application/json"},
567
567
  )
568
- actions.run(source.slug)
568
+ actions.run(source)
569
569
  source.reload()
570
570
  assert source.get_last_job().status == "done"
571
571
 
@@ -600,7 +600,7 @@ def test_flawed_ckan_response(app, rmock):
600
600
  status_code=200,
601
601
  headers={"Content-Type": "application/json"},
602
602
  )
603
- actions.run(source.slug)
603
+ actions.run(source)
604
604
  source.reload()
605
605
  assert source.get_last_job().status == "done-errors"
606
606
  assert source.get_last_job().items[0].remote_id == _id
@@ -617,7 +617,7 @@ def test_flawed_ckan_response(app, rmock):
617
617
  status_code=200,
618
618
  headers={"Content-Type": "application/json"},
619
619
  )
620
- actions.run(source.slug)
620
+ actions.run(source)
621
621
  source.reload()
622
622
  assert source.get_last_job().status == "done-errors"
623
623
  assert source.get_last_job().items[0].remote_id == name
@@ -662,7 +662,7 @@ def test_max_items(app, rmock):
662
662
  status_code=200,
663
663
  headers={"Content-Type": "application/json"},
664
664
  )
665
- actions.run(source.slug)
665
+ actions.run(source)
666
666
  source.reload()
667
667
  assert source.get_last_job().status == "done"
668
668
  assert len(source.get_last_job().items) == 1
@@ -25,7 +25,7 @@ def test_html_error(rmock, code):
25
25
 
26
26
  rmock.get(API_URL, text=html, status_code=code, headers={"Content-Type": "text/html"})
27
27
 
28
- actions.run(source.slug)
28
+ actions.run(source)
29
29
 
30
30
  source.reload()
31
31
 
@@ -45,7 +45,7 @@ def test_plain_text_error(rmock, code):
45
45
  API_URL, text='"Some error"', status_code=code, headers={"Content-Type": "text/plain"}
46
46
  )
47
47
 
48
- actions.run(source.slug)
48
+ actions.run(source)
49
49
 
50
50
  source.reload()
51
51
 
@@ -66,7 +66,7 @@ def test_200_plain_text_error(rmock):
66
66
 
67
67
  rmock.get(API_URL, text='"Some error"', status_code=200, headers={"Content-Type": "text/plain"})
68
68
 
69
- actions.run(source.slug)
69
+ actions.run(source)
70
70
 
71
71
  source.reload()
72
72
 
@@ -84,7 +84,7 @@ def test_standard_api_json_error(rmock):
84
84
 
85
85
  rmock.get(API_URL, json=json, status_code=200, headers={"Content-Type": "application/json"})
86
86
 
87
- actions.run(source.slug)
87
+ actions.run(source)
88
88
 
89
89
  source.reload()
90
90
 
@@ -106,7 +106,7 @@ def test_standard_api_json_error_with_details(rmock):
106
106
 
107
107
  rmock.get(API_URL, json=json, status_code=200, headers={"Content-Type": "application/json"})
108
108
 
109
- actions.run(source.slug)
109
+ actions.run(source)
110
110
 
111
111
  source.reload()
112
112
 
@@ -129,7 +129,7 @@ def test_standard_api_json_error_with_details_and_type(rmock):
129
129
 
130
130
  rmock.get(API_URL, json=json, status_code=200, headers={"Content-Type": "application/json"})
131
131
 
132
- actions.run(source.slug)
132
+ actions.run(source)
133
133
 
134
134
  source.reload()
135
135
 
@@ -26,7 +26,7 @@ def test_include_org_filter(ckan, rmock):
26
26
  headers={"Content-Type": "application/json"},
27
27
  )
28
28
 
29
- actions.run(source.slug)
29
+ actions.run(source)
30
30
  source.reload()
31
31
 
32
32
  assert rmock.call_count == 1
@@ -50,7 +50,7 @@ def test_exclude_org_filter(ckan, rmock):
50
50
  headers={"Content-Type": "application/json"},
51
51
  )
52
52
 
53
- actions.run(source.slug)
53
+ actions.run(source)
54
54
  source.reload()
55
55
 
56
56
  assert rmock.call_count == 1
@@ -72,7 +72,7 @@ def test_tag_filter(ckan, rmock):
72
72
  headers={"Content-Type": "application/json"},
73
73
  )
74
74
 
75
- actions.run(source.slug)
75
+ actions.run(source)
76
76
  source.reload()
77
77
 
78
78
  assert rmock.call_count == 1
@@ -95,7 +95,7 @@ def test_exclude_tag_filter(ckan, rmock):
95
95
  headers={"Content-Type": "application/json"},
96
96
  )
97
97
 
98
- actions.run(source.slug)
98
+ actions.run(source)
99
99
  source.reload()
100
100
 
101
101
  assert rmock.call_count == 1
@@ -122,7 +122,7 @@ def test_can_have_multiple_filters(ckan, rmock):
122
122
  headers={"Content-Type": "application/json"},
123
123
  )
124
124
 
125
- actions.run(source.slug)
125
+ actions.run(source)
126
126
  source.reload()
127
127
 
128
128
  assert rmock.call_count == 1
@@ -54,7 +54,7 @@ def test_dkan_french_w_license(app, rmock):
54
54
  rmock.get(
55
55
  PACKAGE_SHOW_URL, json=data, status_code=200, headers={"Content-Type": "application/json"}
56
56
  )
57
- actions.run(source.slug)
57
+ actions.run(source)
58
58
  source.reload()
59
59
  assert source.get_last_job().status == "done"
60
60