framework-py 0.1.0.dev0__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.
Files changed (63) hide show
  1. framework/__init__.py +250 -0
  2. framework/__main__.py +89 -0
  3. framework/_assets/hooks/pre-commit +59 -0
  4. framework/_assets/init.sql +63 -0
  5. framework/_assets/schema/layer.v1.json +605 -0
  6. framework/_assets/schema/layers.v1.json +791 -0
  7. framework/_assets/schema/spec.v1.json +604 -0
  8. framework/_log.py +29 -0
  9. framework/_paths.py +45 -0
  10. framework/_secretservice.py +69 -0
  11. framework/_time.py +11 -0
  12. framework/_wincred.py +105 -0
  13. framework/_yaml.py +90 -0
  14. framework/ai.py +204 -0
  15. framework/bootstrap.py +206 -0
  16. framework/cache.py +335 -0
  17. framework/catalog.py +193 -0
  18. framework/cloud.py +899 -0
  19. framework/config_home.py +194 -0
  20. framework/connections.py +442 -0
  21. framework/console.py +41 -0
  22. framework/create.py +579 -0
  23. framework/data.py +519 -0
  24. framework/db.py +222 -0
  25. framework/dotenv.py +79 -0
  26. framework/errors.py +39 -0
  27. framework/global_config.py +238 -0
  28. framework/hooks.py +364 -0
  29. framework/integrity.py +22 -0
  30. framework/notebooks.py +384 -0
  31. framework/outputs.py +324 -0
  32. framework/packages.py +276 -0
  33. framework/project.py +52 -0
  34. framework/py.typed +0 -0
  35. framework/quarto.py +163 -0
  36. framework/scaffold.py +269 -0
  37. framework/scratch.py +108 -0
  38. framework/security.py +646 -0
  39. framework/settings.py +439 -0
  40. framework/spec/__init__.py +0 -0
  41. framework/spec/check.py +211 -0
  42. framework/spec/merge.py +195 -0
  43. framework/spec/resolve.py +254 -0
  44. framework/storage.py +516 -0
  45. framework/templates/defaults.yml +144 -0
  46. framework/templates/gitignore/course +120 -0
  47. framework/templates/gitignore/presentation +114 -0
  48. framework/templates/gitignore/project +108 -0
  49. framework/templates/gitignore/sensitive +139 -0
  50. framework/templates/skills/framework-data/SKILL.md +47 -0
  51. framework/templates/skills/framework-outputs/SKILL.md +68 -0
  52. framework/templates/skills/framework-packages/SKILL.md +33 -0
  53. framework/templates/skills/framework-sensitive-data/SKILL.md +38 -0
  54. framework/templates/skills/framework-workflow/SKILL.md +58 -0
  55. framework/templates/stubs/notebook-default.ipynb +34 -0
  56. framework/templates/stubs/notebook-default.qmd +43 -0
  57. framework/templates/stubs/notebook-minimal.qmd +15 -0
  58. framework/templates/stubs/notebook-revealjs.qmd +34 -0
  59. framework/templates/stubs/script-default.py +18 -0
  60. framework_py-0.1.0.dev0.dist-info/METADATA +111 -0
  61. framework_py-0.1.0.dev0.dist-info/RECORD +63 -0
  62. framework_py-0.1.0.dev0.dist-info/WHEEL +4 -0
  63. framework_py-0.1.0.dev0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,791 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://framework.pub/schema/layers/v1.json",
4
+ "title": "Framework project layers",
5
+ "description": "Unmerged layers for one project, bottom to top, excluding package defaults. Read by project_create_from_layers() and returned by pull v2.",
6
+ "type": "object",
7
+ "properties": {
8
+ "spec_version": {
9
+ "const": 1
10
+ },
11
+ "name": {
12
+ "type": "string",
13
+ "minLength": 1
14
+ },
15
+ "author": {
16
+ "type": "object",
17
+ "properties": {
18
+ "name": {
19
+ "type": "string"
20
+ },
21
+ "email": {
22
+ "type": "string"
23
+ },
24
+ "affiliation": {
25
+ "type": "string"
26
+ },
27
+ "orcid": {
28
+ "type": "string"
29
+ },
30
+ "url": {
31
+ "type": "string"
32
+ },
33
+ "affiliations": {
34
+ "type": "array",
35
+ "items": {
36
+ "type": "object",
37
+ "properties": {
38
+ "name": {
39
+ "type": "string",
40
+ "minLength": 1
41
+ },
42
+ "department": {
43
+ "type": "string"
44
+ },
45
+ "city": {
46
+ "type": "string"
47
+ },
48
+ "country": {
49
+ "type": "string"
50
+ }
51
+ },
52
+ "additionalProperties": false,
53
+ "required": [
54
+ "name"
55
+ ]
56
+ }
57
+ }
58
+ },
59
+ "additionalProperties": false,
60
+ "required": [
61
+ "name",
62
+ "email",
63
+ "affiliation"
64
+ ]
65
+ },
66
+ "layers": {
67
+ "type": "array",
68
+ "items": {
69
+ "type": "object",
70
+ "properties": {
71
+ "kind": {
72
+ "type": "string",
73
+ "enum": [
74
+ "settings",
75
+ "base",
76
+ "facet",
77
+ "blueprint",
78
+ "project"
79
+ ],
80
+ "description": "Labels the layer in conflicts and gitignore blocks. Without it the label is 'layer N' (1-based)."
81
+ },
82
+ "key": {
83
+ "type": "string"
84
+ },
85
+ "version": {
86
+ "type": "integer"
87
+ },
88
+ "layer": {
89
+ "$ref": "#/definitions/layer"
90
+ }
91
+ },
92
+ "additionalProperties": false,
93
+ "required": [
94
+ "layer"
95
+ ]
96
+ }
97
+ },
98
+ "source": {
99
+ "type": "object",
100
+ "properties": {
101
+ "origin": {
102
+ "type": "string",
103
+ "enum": [
104
+ "cloud",
105
+ "cli",
106
+ "r",
107
+ "python"
108
+ ]
109
+ },
110
+ "fragments": {
111
+ "type": "array",
112
+ "items": {
113
+ "type": "object",
114
+ "properties": {
115
+ "kind": {
116
+ "type": "string",
117
+ "enum": [
118
+ "base",
119
+ "facet",
120
+ "blueprint"
121
+ ]
122
+ },
123
+ "key": {
124
+ "type": "string"
125
+ },
126
+ "version": {
127
+ "type": "integer"
128
+ }
129
+ },
130
+ "additionalProperties": false,
131
+ "required": [
132
+ "kind",
133
+ "key"
134
+ ]
135
+ }
136
+ },
137
+ "blueprint": {
138
+ "type": "object",
139
+ "properties": {
140
+ "key": {
141
+ "type": "string"
142
+ },
143
+ "version": {
144
+ "type": "integer"
145
+ }
146
+ },
147
+ "additionalProperties": false,
148
+ "required": [
149
+ "key"
150
+ ]
151
+ },
152
+ "study_plan": {
153
+ "type": "object",
154
+ "properties": {
155
+ "id": {
156
+ "type": "string"
157
+ },
158
+ "version": {
159
+ "type": "integer"
160
+ }
161
+ },
162
+ "additionalProperties": false,
163
+ "required": [
164
+ "id"
165
+ ]
166
+ },
167
+ "framework_version": {
168
+ "type": "string",
169
+ "description": "Version of the R or Python package that created the project"
170
+ },
171
+ "fw_version": {
172
+ "type": "string",
173
+ "description": "Version of fw that created the project (Stata scaffolding)"
174
+ }
175
+ },
176
+ "additionalProperties": false,
177
+ "required": [
178
+ "origin"
179
+ ]
180
+ }
181
+ },
182
+ "required": [
183
+ "spec_version",
184
+ "name",
185
+ "layers"
186
+ ],
187
+ "additionalProperties": false,
188
+ "definitions": {
189
+ "package": {
190
+ "type": "object",
191
+ "properties": {
192
+ "source": {
193
+ "type": "string",
194
+ "enum": [
195
+ "cran",
196
+ "github",
197
+ "bioc",
198
+ "pypi"
199
+ ]
200
+ },
201
+ "version": {
202
+ "anyOf": [
203
+ {
204
+ "type": "string"
205
+ },
206
+ {
207
+ "type": "null"
208
+ }
209
+ ]
210
+ },
211
+ "repo": {
212
+ "anyOf": [
213
+ {
214
+ "type": "string"
215
+ },
216
+ {
217
+ "type": "null"
218
+ }
219
+ ]
220
+ },
221
+ "ref": {
222
+ "anyOf": [
223
+ {
224
+ "type": "string"
225
+ },
226
+ {
227
+ "type": "null"
228
+ }
229
+ ]
230
+ },
231
+ "auto_attach": {
232
+ "type": "boolean"
233
+ }
234
+ },
235
+ "additionalProperties": false,
236
+ "required": [
237
+ "source",
238
+ "auto_attach"
239
+ ]
240
+ },
241
+ "extra_directory": {
242
+ "type": "object",
243
+ "properties": {
244
+ "label": {
245
+ "type": "string"
246
+ },
247
+ "path": {
248
+ "type": "string",
249
+ "pattern": "^(?!/)(?!.*(^|/)\\.\\.(/|$))[^\\\\]+$"
250
+ }
251
+ },
252
+ "additionalProperties": false,
253
+ "required": [
254
+ "path"
255
+ ]
256
+ },
257
+ "file": {
258
+ "type": "object",
259
+ "properties": {
260
+ "content": {
261
+ "type": "string"
262
+ },
263
+ "template": {
264
+ "type": "boolean",
265
+ "description": "Replace {{project_name}}, {{author}}, {{author_email}}, {{affiliation}}, and {{date}}"
266
+ }
267
+ },
268
+ "additionalProperties": false,
269
+ "required": [
270
+ "content"
271
+ ]
272
+ },
273
+ "skill": {
274
+ "oneOf": [
275
+ {
276
+ "type": "object",
277
+ "properties": {
278
+ "package": {
279
+ "const": true
280
+ }
281
+ },
282
+ "additionalProperties": false,
283
+ "required": [
284
+ "package"
285
+ ]
286
+ },
287
+ {
288
+ "type": "object",
289
+ "properties": {
290
+ "content": {
291
+ "type": "string",
292
+ "minLength": 1,
293
+ "description": "Full SKILL.md text, including frontmatter"
294
+ },
295
+ "files": {
296
+ "type": "object",
297
+ "additionalProperties": {
298
+ "type": "string"
299
+ },
300
+ "propertyNames": {
301
+ "pattern": "^(?!/)(?!.*(^|/)\\.\\.(/|$))[^\\\\]+$"
302
+ }
303
+ }
304
+ },
305
+ "additionalProperties": false,
306
+ "required": [
307
+ "content"
308
+ ]
309
+ }
310
+ ]
311
+ },
312
+ "connection": {
313
+ "type": "object",
314
+ "properties": {
315
+ "driver": {
316
+ "type": "string",
317
+ "minLength": 1
318
+ }
319
+ },
320
+ "additionalProperties": true,
321
+ "required": [
322
+ "driver"
323
+ ]
324
+ },
325
+ "layer": {
326
+ "title": "Framework project spec layer",
327
+ "description": "One unmerged layer of a project spec. Every field is optional, and a null map entry removes that key when spec_resolve() merges layers.",
328
+ "type": "object",
329
+ "properties": {
330
+ "spec_version": {
331
+ "const": 1
332
+ },
333
+ "name": {
334
+ "type": "string",
335
+ "minLength": 1
336
+ },
337
+ "type": {
338
+ "type": "string",
339
+ "enum": [
340
+ "project",
341
+ "project_sensitive",
342
+ "course",
343
+ "presentation",
344
+ "bare"
345
+ ]
346
+ },
347
+ "language": {
348
+ "type": "string",
349
+ "enum": [
350
+ "r",
351
+ "python",
352
+ "stata"
353
+ ],
354
+ "description": "Primary language. The R package builds r, the Python package builds python, and fw builds stata (scaffolding only). A layers file with no language means r."
355
+ },
356
+ "author": {
357
+ "type": "object",
358
+ "properties": {
359
+ "name": {
360
+ "type": "string"
361
+ },
362
+ "email": {
363
+ "type": "string"
364
+ },
365
+ "affiliation": {
366
+ "type": "string"
367
+ },
368
+ "orcid": {
369
+ "type": "string"
370
+ },
371
+ "url": {
372
+ "type": "string"
373
+ },
374
+ "affiliations": {
375
+ "type": "array",
376
+ "items": {
377
+ "type": "object",
378
+ "properties": {
379
+ "name": {
380
+ "type": "string",
381
+ "minLength": 1
382
+ },
383
+ "department": {
384
+ "type": "string"
385
+ },
386
+ "city": {
387
+ "type": "string"
388
+ },
389
+ "country": {
390
+ "type": "string"
391
+ }
392
+ },
393
+ "additionalProperties": false
394
+ }
395
+ }
396
+ },
397
+ "additionalProperties": false
398
+ },
399
+ "directories": {
400
+ "type": "object",
401
+ "additionalProperties": {
402
+ "anyOf": [
403
+ {
404
+ "type": "string",
405
+ "pattern": "^(?!/)(?!.*(^|/)\\.\\.(/|$))[^\\\\]+$"
406
+ },
407
+ {
408
+ "type": "null"
409
+ }
410
+ ]
411
+ },
412
+ "propertyNames": {
413
+ "pattern": "^[a-z][a-z0-9_]*$"
414
+ }
415
+ },
416
+ "extra_directories": {
417
+ "type": "object",
418
+ "additionalProperties": {
419
+ "anyOf": [
420
+ {
421
+ "$ref": "#/definitions/extra_directory"
422
+ },
423
+ {
424
+ "type": "null"
425
+ }
426
+ ]
427
+ },
428
+ "propertyNames": {
429
+ "pattern": "^[a-z][a-z0-9_]*$"
430
+ }
431
+ },
432
+ "render_dirs": {
433
+ "type": "object",
434
+ "additionalProperties": {
435
+ "anyOf": [
436
+ {
437
+ "type": "string",
438
+ "pattern": "^(?!/)(?!.*(^|/)\\.\\.(/|$))[^\\\\]+$"
439
+ },
440
+ {
441
+ "type": "null"
442
+ }
443
+ ]
444
+ },
445
+ "propertyNames": {
446
+ "pattern": "^[a-z][a-z0-9_]*$"
447
+ }
448
+ },
449
+ "packages": {
450
+ "type": "object",
451
+ "properties": {
452
+ "use_renv": {
453
+ "type": "boolean"
454
+ },
455
+ "default_packages": {
456
+ "type": "object",
457
+ "additionalProperties": {
458
+ "anyOf": [
459
+ {
460
+ "$ref": "#/definitions/package"
461
+ },
462
+ {
463
+ "type": "null"
464
+ }
465
+ ]
466
+ },
467
+ "description": "Package name -> spec. JSON object key order is not kept (Postgres JSONB sorts keys).",
468
+ "propertyNames": {
469
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*$"
470
+ }
471
+ }
472
+ },
473
+ "additionalProperties": false
474
+ },
475
+ "git": {
476
+ "type": "object",
477
+ "properties": {
478
+ "use_git": {
479
+ "type": "boolean"
480
+ },
481
+ "hooks": {
482
+ "type": "object",
483
+ "additionalProperties": {
484
+ "anyOf": [
485
+ {
486
+ "type": "boolean"
487
+ },
488
+ {
489
+ "type": "null"
490
+ }
491
+ ]
492
+ },
493
+ "propertyNames": {
494
+ "pattern": "^[a-z][a-z0-9_]*$"
495
+ }
496
+ },
497
+ "gitignore_content": {
498
+ "type": "string"
499
+ }
500
+ },
501
+ "additionalProperties": false
502
+ },
503
+ "ai": {
504
+ "type": "object",
505
+ "properties": {
506
+ "enabled": {
507
+ "type": "boolean"
508
+ },
509
+ "assistants": {
510
+ "type": "object",
511
+ "propertyNames": {
512
+ "enum": [
513
+ "claude",
514
+ "codex",
515
+ "copilot"
516
+ ]
517
+ },
518
+ "additionalProperties": {
519
+ "anyOf": [
520
+ {
521
+ "type": "boolean"
522
+ },
523
+ {
524
+ "type": "null"
525
+ }
526
+ ]
527
+ },
528
+ "description": "Assistant -> true to include. In a layer, false or null removes it."
529
+ },
530
+ "agents_md": {
531
+ "type": "string",
532
+ "enum": [
533
+ "stub",
534
+ "none"
535
+ ]
536
+ }
537
+ },
538
+ "additionalProperties": false
539
+ },
540
+ "scaffold": {
541
+ "type": "object",
542
+ "properties": {
543
+ "seed_on_scaffold": {
544
+ "type": "boolean"
545
+ },
546
+ "seed": {
547
+ "type": "string"
548
+ },
549
+ "set_theme_on_scaffold": {
550
+ "type": "boolean"
551
+ },
552
+ "ggplot_theme": {
553
+ "type": "string"
554
+ },
555
+ "source_all_functions": {
556
+ "type": "boolean"
557
+ },
558
+ "notebook_format": {
559
+ "type": "string",
560
+ "enum": [
561
+ "quarto",
562
+ "rmarkdown",
563
+ "jupyter"
564
+ ]
565
+ },
566
+ "ide": {
567
+ "type": "string",
568
+ "enum": [
569
+ "vscode",
570
+ "positron",
571
+ "rstudio",
572
+ "both",
573
+ "none"
574
+ ]
575
+ }
576
+ },
577
+ "additionalProperties": false
578
+ },
579
+ "quarto": {
580
+ "type": "object",
581
+ "description": "Passed through to _quarto.yml generation"
582
+ },
583
+ "connections": {
584
+ "type": "object",
585
+ "properties": {
586
+ "default_database": {
587
+ "anyOf": [
588
+ {
589
+ "type": "string"
590
+ },
591
+ {
592
+ "type": "null"
593
+ }
594
+ ]
595
+ },
596
+ "default_storage_bucket": {
597
+ "anyOf": [
598
+ {
599
+ "type": "string"
600
+ },
601
+ {
602
+ "type": "null"
603
+ }
604
+ ]
605
+ },
606
+ "databases": {
607
+ "type": "object",
608
+ "additionalProperties": {
609
+ "anyOf": [
610
+ {
611
+ "$ref": "#/definitions/connection"
612
+ },
613
+ {
614
+ "type": "null"
615
+ }
616
+ ]
617
+ },
618
+ "propertyNames": {
619
+ "pattern": "^[a-z][a-z0-9_]*$"
620
+ }
621
+ },
622
+ "storage_buckets": {
623
+ "type": "object",
624
+ "additionalProperties": {
625
+ "anyOf": [
626
+ {
627
+ "$ref": "#/definitions/connection"
628
+ },
629
+ {
630
+ "type": "null"
631
+ }
632
+ ]
633
+ },
634
+ "propertyNames": {
635
+ "pattern": "^[a-z][a-z0-9_]*$"
636
+ }
637
+ }
638
+ },
639
+ "additionalProperties": false
640
+ },
641
+ "security": {
642
+ "type": "object",
643
+ "properties": {
644
+ "sensitive": {
645
+ "type": "boolean"
646
+ }
647
+ },
648
+ "additionalProperties": false
649
+ },
650
+ "env": {
651
+ "type": "object",
652
+ "additionalProperties": {
653
+ "anyOf": [
654
+ {
655
+ "type": "string"
656
+ },
657
+ {
658
+ "type": "null"
659
+ }
660
+ ]
661
+ },
662
+ "description": "Variables written to .env. Secret-looking names must be empty.",
663
+ "propertyNames": {
664
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
665
+ }
666
+ },
667
+ "data_hooks": {
668
+ "type": "object",
669
+ "additionalProperties": {
670
+ "anyOf": [
671
+ {
672
+ "type": "string",
673
+ "pattern": "^[^:]+\\.(R|py)::[A-Za-z_.][A-Za-z0-9._]*$"
674
+ },
675
+ {
676
+ "type": "null"
677
+ }
678
+ ]
679
+ },
680
+ "description": "Directory key -> 'path/to/file.R::function'",
681
+ "propertyNames": {
682
+ "pattern": "^[a-z][a-z0-9_]*$"
683
+ }
684
+ },
685
+ "files": {
686
+ "type": "object",
687
+ "additionalProperties": {
688
+ "anyOf": [
689
+ {
690
+ "$ref": "#/definitions/file"
691
+ },
692
+ {
693
+ "type": "null"
694
+ }
695
+ ]
696
+ },
697
+ "propertyNames": {
698
+ "pattern": "^(?!/)(?!.*(^|/)\\.\\.(/|$))[^\\\\]+$"
699
+ }
700
+ },
701
+ "skills": {
702
+ "type": "object",
703
+ "additionalProperties": {
704
+ "anyOf": [
705
+ {
706
+ "$ref": "#/definitions/skill"
707
+ },
708
+ {
709
+ "type": "null"
710
+ }
711
+ ]
712
+ },
713
+ "propertyNames": {
714
+ "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
715
+ }
716
+ },
717
+ "source": {
718
+ "type": "object",
719
+ "properties": {
720
+ "origin": {
721
+ "type": "string",
722
+ "enum": [
723
+ "cloud",
724
+ "cli",
725
+ "r",
726
+ "python"
727
+ ]
728
+ },
729
+ "fragments": {
730
+ "type": "array",
731
+ "items": {
732
+ "type": "object",
733
+ "properties": {
734
+ "kind": {
735
+ "type": "string",
736
+ "enum": [
737
+ "base",
738
+ "facet",
739
+ "blueprint"
740
+ ]
741
+ },
742
+ "key": {
743
+ "type": "string"
744
+ },
745
+ "version": {
746
+ "type": "integer"
747
+ }
748
+ },
749
+ "additionalProperties": false
750
+ }
751
+ },
752
+ "blueprint": {
753
+ "type": "object",
754
+ "properties": {
755
+ "key": {
756
+ "type": "string"
757
+ },
758
+ "version": {
759
+ "type": "integer"
760
+ }
761
+ },
762
+ "additionalProperties": false
763
+ },
764
+ "study_plan": {
765
+ "type": "object",
766
+ "properties": {
767
+ "id": {
768
+ "type": "string"
769
+ },
770
+ "version": {
771
+ "type": "integer"
772
+ }
773
+ },
774
+ "additionalProperties": false
775
+ },
776
+ "framework_version": {
777
+ "type": "string",
778
+ "description": "Version of the R or Python package that created the project"
779
+ },
780
+ "fw_version": {
781
+ "type": "string",
782
+ "description": "Version of fw that created the project (Stata scaffolding)"
783
+ }
784
+ },
785
+ "additionalProperties": false
786
+ }
787
+ },
788
+ "additionalProperties": false
789
+ }
790
+ }
791
+ }