lairs 0.1.0__tar.gz

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 (336) hide show
  1. lairs-0.1.0/.github/workflows/ci.yml +109 -0
  2. lairs-0.1.0/.github/workflows/docs.yml +70 -0
  3. lairs-0.1.0/.github/workflows/release.yml +169 -0
  4. lairs-0.1.0/.gitignore +39 -0
  5. lairs-0.1.0/CHANGELOG.md +65 -0
  6. lairs-0.1.0/CODE_OF_CONDUCT.md +133 -0
  7. lairs-0.1.0/CONTRIBUTING.md +163 -0
  8. lairs-0.1.0/LICENSE +21 -0
  9. lairs-0.1.0/PKG-INFO +216 -0
  10. lairs-0.1.0/README.md +120 -0
  11. lairs-0.1.0/docs/concepts/anchors-and-modality.md +118 -0
  12. lairs-0.1.0/docs/concepts/architecture.md +139 -0
  13. lairs-0.1.0/docs/concepts/generated-models.md +122 -0
  14. lairs-0.1.0/docs/concepts/index.md +33 -0
  15. lairs-0.1.0/docs/concepts/integrations.md +133 -0
  16. lairs-0.1.0/docs/concepts/layers-data-model.md +219 -0
  17. lairs-0.1.0/docs/concepts/reproducibility.md +123 -0
  18. lairs-0.1.0/docs/css/custom.css +87 -0
  19. lairs-0.1.0/docs/css/pygments.css +85 -0
  20. lairs-0.1.0/docs/development/codegen.md +56 -0
  21. lairs-0.1.0/docs/development/index.md +129 -0
  22. lairs-0.1.0/docs/development/releasing.md +83 -0
  23. lairs-0.1.0/docs/development/testing.md +84 -0
  24. lairs-0.1.0/docs/guide/authoring.md +204 -0
  25. lairs-0.1.0/docs/guide/cli.md +243 -0
  26. lairs-0.1.0/docs/guide/codecs.md +123 -0
  27. lairs-0.1.0/docs/guide/codegen.md +115 -0
  28. lairs-0.1.0/docs/guide/dataset-api.md +148 -0
  29. lairs-0.1.0/docs/guide/explorer.md +200 -0
  30. lairs-0.1.0/docs/guide/exporters.md +195 -0
  31. lairs-0.1.0/docs/guide/index.md +85 -0
  32. lairs-0.1.0/docs/guide/knowledge-bases.md +131 -0
  33. lairs-0.1.0/docs/guide/media.md +179 -0
  34. lairs-0.1.0/docs/guide/reading-pds.md +244 -0
  35. lairs-0.1.0/docs/guide/store.md +205 -0
  36. lairs-0.1.0/docs/guide/tracking.md +79 -0
  37. lairs-0.1.0/docs/index.md +68 -0
  38. lairs-0.1.0/docs/project/stability.md +42 -0
  39. lairs-0.1.0/docs/reference/atproto.md +76 -0
  40. lairs-0.1.0/docs/reference/author.md +16 -0
  41. lairs-0.1.0/docs/reference/cli.md +43 -0
  42. lairs-0.1.0/docs/reference/codecs.md +20 -0
  43. lairs-0.1.0/docs/reference/codegen.md +37 -0
  44. lairs-0.1.0/docs/reference/data.md +19 -0
  45. lairs-0.1.0/docs/reference/discovery.md +91 -0
  46. lairs-0.1.0/docs/reference/explorer.md +51 -0
  47. lairs-0.1.0/docs/reference/exporters.md +26 -0
  48. lairs-0.1.0/docs/reference/index.md +69 -0
  49. lairs-0.1.0/docs/reference/kb.md +26 -0
  50. lairs-0.1.0/docs/reference/media.md +44 -0
  51. lairs-0.1.0/docs/reference/ports.md +18 -0
  52. lairs-0.1.0/docs/reference/records.md +92 -0
  53. lairs-0.1.0/docs/reference/registry.md +8 -0
  54. lairs-0.1.0/docs/reference/store.md +33 -0
  55. lairs-0.1.0/docs/reference/tracking.md +9 -0
  56. lairs-0.1.0/docs/reference/types.md +9 -0
  57. lairs-0.1.0/docs/tutorial/01-reading-a-corpus.md +212 -0
  58. lairs-0.1.0/docs/tutorial/02-materializing-views.md +102 -0
  59. lairs-0.1.0/docs/tutorial/03-authoring-and-publishing.md +175 -0
  60. lairs-0.1.0/docs/tutorial/index.md +44 -0
  61. lairs-0.1.0/lairs/__init__.py +142 -0
  62. lairs-0.1.0/lairs/_aturi.py +59 -0
  63. lairs-0.1.0/lairs/_codegen/__init__.py +30 -0
  64. lairs-0.1.0/lairs/_codegen/emit.py +450 -0
  65. lairs-0.1.0/lairs/_codegen/manifest.py +99 -0
  66. lairs-0.1.0/lairs/_codegen/pipeline.py +366 -0
  67. lairs-0.1.0/lairs/_codegen/schema_to_spec.py +627 -0
  68. lairs-0.1.0/lairs/_types.py +38 -0
  69. lairs-0.1.0/lairs/atproto/__init__.py +84 -0
  70. lairs-0.1.0/lairs/atproto/_car.py +107 -0
  71. lairs-0.1.0/lairs/atproto/appview.py +238 -0
  72. lairs-0.1.0/lairs/atproto/auth.py +383 -0
  73. lairs-0.1.0/lairs/atproto/blobs.py +250 -0
  74. lairs-0.1.0/lairs/atproto/firehose.py +374 -0
  75. lairs-0.1.0/lairs/atproto/identity.py +419 -0
  76. lairs-0.1.0/lairs/atproto/pds.py +873 -0
  77. lairs-0.1.0/lairs/author/__init__.py +60 -0
  78. lairs-0.1.0/lairs/author/builders.py +595 -0
  79. lairs-0.1.0/lairs/author/publish.py +1391 -0
  80. lairs-0.1.0/lairs/cli.py +1403 -0
  81. lairs-0.1.0/lairs/data/__init__.py +34 -0
  82. lairs-0.1.0/lairs/data/corpus.py +806 -0
  83. lairs-0.1.0/lairs/data/dataset.py +438 -0
  84. lairs-0.1.0/lairs/data/features.py +252 -0
  85. lairs-0.1.0/lairs/discovery/__init__.py +46 -0
  86. lairs-0.1.0/lairs/discovery/accelerator.py +137 -0
  87. lairs-0.1.0/lairs/discovery/actor.py +299 -0
  88. lairs-0.1.0/lairs/discovery/cards.py +335 -0
  89. lairs-0.1.0/lairs/discovery/federated.py +144 -0
  90. lairs-0.1.0/lairs/discovery/index.py +341 -0
  91. lairs-0.1.0/lairs/discovery/ingest.py +362 -0
  92. lairs-0.1.0/lairs/discovery/links.py +169 -0
  93. lairs-0.1.0/lairs/discovery/models.py +221 -0
  94. lairs-0.1.0/lairs/discovery/query.py +175 -0
  95. lairs-0.1.0/lairs/discovery/summary.py +283 -0
  96. lairs-0.1.0/lairs/integrations/__init__.py +43 -0
  97. lairs-0.1.0/lairs/integrations/codecs/__init__.py +82 -0
  98. lairs-0.1.0/lairs/integrations/codecs/brat.py +795 -0
  99. lairs-0.1.0/lairs/integrations/codecs/conllu.py +987 -0
  100. lairs-0.1.0/lairs/integrations/hf/__init__.py +41 -0
  101. lairs-0.1.0/lairs/integrations/hf/datasets.py +527 -0
  102. lairs-0.1.0/lairs/integrations/hf/hub.py +480 -0
  103. lairs-0.1.0/lairs/integrations/kb/__init__.py +78 -0
  104. lairs-0.1.0/lairs/integrations/kb/glazing.py +480 -0
  105. lairs-0.1.0/lairs/integrations/kb/reconciliation.py +475 -0
  106. lairs-0.1.0/lairs/integrations/kb/wikidata.py +590 -0
  107. lairs-0.1.0/lairs/integrations/ports.py +217 -0
  108. lairs-0.1.0/lairs/integrations/registry.py +279 -0
  109. lairs-0.1.0/lairs/integrations/tfdata.py +428 -0
  110. lairs-0.1.0/lairs/integrations/torch.py +497 -0
  111. lairs-0.1.0/lairs/integrations/tracking.py +297 -0
  112. lairs-0.1.0/lairs/integrations/webdataset.py +548 -0
  113. lairs-0.1.0/lairs/lexicons/MANIFEST.toml +18 -0
  114. lairs-0.1.0/lairs/lexicons/README.md +17 -0
  115. lairs-0.1.0/lairs/lexicons/pub/layers/alignment/alignment.json +130 -0
  116. lairs-0.1.0/lairs/lexicons/pub/layers/alignment/getAlignment.json +30 -0
  117. lairs-0.1.0/lairs/lexicons/pub/layers/alignment/listAlignments.json +43 -0
  118. lairs-0.1.0/lairs/lexicons/pub/layers/annotation/annotationLayer.json +239 -0
  119. lairs-0.1.0/lairs/lexicons/pub/layers/annotation/clusterSet.json +86 -0
  120. lairs-0.1.0/lairs/lexicons/pub/layers/annotation/defs.json +165 -0
  121. lairs-0.1.0/lairs/lexicons/pub/layers/annotation/getAnnotationLayer.json +30 -0
  122. lairs-0.1.0/lairs/lexicons/pub/layers/annotation/getClusterSet.json +30 -0
  123. lairs-0.1.0/lairs/lexicons/pub/layers/annotation/listAnnotationLayers.json +44 -0
  124. lairs-0.1.0/lairs/lexicons/pub/layers/annotation/listClusterSets.json +43 -0
  125. lairs-0.1.0/lairs/lexicons/pub/layers/authAnnotator.json +64 -0
  126. lairs-0.1.0/lairs/lexicons/pub/layers/authCorpusManager.json +64 -0
  127. lairs-0.1.0/lairs/lexicons/pub/layers/authExperimenter.json +52 -0
  128. lairs-0.1.0/lairs/lexicons/pub/layers/authFull.json +110 -0
  129. lairs-0.1.0/lairs/lexicons/pub/layers/authOntologyEditor.json +46 -0
  130. lairs-0.1.0/lairs/lexicons/pub/layers/authReadOnly.json +73 -0
  131. lairs-0.1.0/lairs/lexicons/pub/layers/changelog/defs.json +107 -0
  132. lairs-0.1.0/lairs/lexicons/pub/layers/changelog/entry.json +56 -0
  133. lairs-0.1.0/lairs/lexicons/pub/layers/changelog/getEntry.json +30 -0
  134. lairs-0.1.0/lairs/lexicons/pub/layers/changelog/listByCollection.json +45 -0
  135. lairs-0.1.0/lairs/lexicons/pub/layers/changelog/listEntries.json +46 -0
  136. lairs-0.1.0/lairs/lexicons/pub/layers/corpus/corpus.json +110 -0
  137. lairs-0.1.0/lairs/lexicons/pub/layers/corpus/defs.json +173 -0
  138. lairs-0.1.0/lairs/lexicons/pub/layers/corpus/getCorpus.json +30 -0
  139. lairs-0.1.0/lairs/lexicons/pub/layers/corpus/getMembership.json +30 -0
  140. lairs-0.1.0/lairs/lexicons/pub/layers/corpus/listCorpora.json +85 -0
  141. lairs-0.1.0/lairs/lexicons/pub/layers/corpus/listMemberships.json +43 -0
  142. lairs-0.1.0/lairs/lexicons/pub/layers/corpus/membership.json +55 -0
  143. lairs-0.1.0/lairs/lexicons/pub/layers/defs.json +972 -0
  144. lairs-0.1.0/lairs/lexicons/pub/layers/eprint/dataLink.json +90 -0
  145. lairs-0.1.0/lairs/lexicons/pub/layers/eprint/defs.json +248 -0
  146. lairs-0.1.0/lairs/lexicons/pub/layers/eprint/eprint.json +119 -0
  147. lairs-0.1.0/lairs/lexicons/pub/layers/eprint/getDataLink.json +30 -0
  148. lairs-0.1.0/lairs/lexicons/pub/layers/eprint/getEprint.json +30 -0
  149. lairs-0.1.0/lairs/lexicons/pub/layers/eprint/listDataLinks.json +43 -0
  150. lairs-0.1.0/lairs/lexicons/pub/layers/eprint/listEprints.json +44 -0
  151. lairs-0.1.0/lairs/lexicons/pub/layers/expression/expression.json +144 -0
  152. lairs-0.1.0/lairs/lexicons/pub/layers/expression/getExpression.json +30 -0
  153. lairs-0.1.0/lairs/lexicons/pub/layers/expression/listExpressions.json +90 -0
  154. lairs-0.1.0/lairs/lexicons/pub/layers/graph/defs.json +47 -0
  155. lairs-0.1.0/lairs/lexicons/pub/layers/graph/getGraphEdge.json +30 -0
  156. lairs-0.1.0/lairs/lexicons/pub/layers/graph/getGraphEdgeSet.json +30 -0
  157. lairs-0.1.0/lairs/lexicons/pub/layers/graph/getGraphNode.json +30 -0
  158. lairs-0.1.0/lairs/lexicons/pub/layers/graph/graphEdge.json +89 -0
  159. lairs-0.1.0/lairs/lexicons/pub/layers/graph/graphEdgeSet.json +98 -0
  160. lairs-0.1.0/lairs/lexicons/pub/layers/graph/graphNode.json +55 -0
  161. lairs-0.1.0/lairs/lexicons/pub/layers/graph/listGraphEdgeSets.json +44 -0
  162. lairs-0.1.0/lairs/lexicons/pub/layers/graph/listGraphEdges.json +45 -0
  163. lairs-0.1.0/lairs/lexicons/pub/layers/graph/listGraphNodes.json +43 -0
  164. lairs-0.1.0/lairs/lexicons/pub/layers/integration/README.md +212 -0
  165. lairs-0.1.0/lairs/lexicons/pub/layers/integration/applyLens.json +61 -0
  166. lairs-0.1.0/lairs/lexicons/pub/layers/integration/getExternal.json +45 -0
  167. lairs-0.1.0/lairs/lexicons/pub/layers/integration/listExternal.json +53 -0
  168. lairs-0.1.0/lairs/lexicons/pub/layers/judgment/agreementReport.json +62 -0
  169. lairs-0.1.0/lairs/lexicons/pub/layers/judgment/defs.json +240 -0
  170. lairs-0.1.0/lairs/lexicons/pub/layers/judgment/experimentDef.json +182 -0
  171. lairs-0.1.0/lairs/lexicons/pub/layers/judgment/getAgreementReport.json +30 -0
  172. lairs-0.1.0/lairs/lexicons/pub/layers/judgment/getExperimentDef.json +30 -0
  173. lairs-0.1.0/lairs/lexicons/pub/layers/judgment/getJudgmentSet.json +30 -0
  174. lairs-0.1.0/lairs/lexicons/pub/layers/judgment/judgmentSet.json +55 -0
  175. lairs-0.1.0/lairs/lexicons/pub/layers/judgment/listAgreementReports.json +43 -0
  176. lairs-0.1.0/lairs/lexicons/pub/layers/judgment/listExperimentDefs.json +44 -0
  177. lairs-0.1.0/lairs/lexicons/pub/layers/judgment/listJudgmentSets.json +42 -0
  178. lairs-0.1.0/lairs/lexicons/pub/layers/media/defs.json +149 -0
  179. lairs-0.1.0/lairs/lexicons/pub/layers/media/getMedia.json +30 -0
  180. lairs-0.1.0/lairs/lexicons/pub/layers/media/listMedia.json +43 -0
  181. lairs-0.1.0/lairs/lexicons/pub/layers/media/media.json +147 -0
  182. lairs-0.1.0/lairs/lexicons/pub/layers/ontology/defs.json +67 -0
  183. lairs-0.1.0/lairs/lexicons/pub/layers/ontology/getOntology.json +30 -0
  184. lairs-0.1.0/lairs/lexicons/pub/layers/ontology/getTypeDef.json +30 -0
  185. lairs-0.1.0/lairs/lexicons/pub/layers/ontology/listOntologies.json +43 -0
  186. lairs-0.1.0/lairs/lexicons/pub/layers/ontology/listTypeDefs.json +43 -0
  187. lairs-0.1.0/lairs/lexicons/pub/layers/ontology/ontology.json +80 -0
  188. lairs-0.1.0/lairs/lexicons/pub/layers/ontology/typeDef.json +83 -0
  189. lairs-0.1.0/lairs/lexicons/pub/layers/persona/getPersona.json +30 -0
  190. lairs-0.1.0/lairs/lexicons/pub/layers/persona/listPersonas.json +44 -0
  191. lairs-0.1.0/lairs/lexicons/pub/layers/persona/persona.json +104 -0
  192. lairs-0.1.0/lairs/lexicons/pub/layers/resource/collection.json +102 -0
  193. lairs-0.1.0/lairs/lexicons/pub/layers/resource/collectionMembership.json +45 -0
  194. lairs-0.1.0/lairs/lexicons/pub/layers/resource/defs.json +164 -0
  195. lairs-0.1.0/lairs/lexicons/pub/layers/resource/entry.json +100 -0
  196. lairs-0.1.0/lairs/lexicons/pub/layers/resource/filling.json +75 -0
  197. lairs-0.1.0/lairs/lexicons/pub/layers/resource/getCollection.json +30 -0
  198. lairs-0.1.0/lairs/lexicons/pub/layers/resource/getCollectionMembership.json +30 -0
  199. lairs-0.1.0/lairs/lexicons/pub/layers/resource/getEntry.json +30 -0
  200. lairs-0.1.0/lairs/lexicons/pub/layers/resource/getFilling.json +30 -0
  201. lairs-0.1.0/lairs/lexicons/pub/layers/resource/getTemplate.json +30 -0
  202. lairs-0.1.0/lairs/lexicons/pub/layers/resource/getTemplateComposition.json +30 -0
  203. lairs-0.1.0/lairs/lexicons/pub/layers/resource/listCollectionMemberships.json +42 -0
  204. lairs-0.1.0/lairs/lexicons/pub/layers/resource/listCollections.json +85 -0
  205. lairs-0.1.0/lairs/lexicons/pub/layers/resource/listEntries.json +82 -0
  206. lairs-0.1.0/lairs/lexicons/pub/layers/resource/listFillings.json +43 -0
  207. lairs-0.1.0/lairs/lexicons/pub/layers/resource/listTemplateCompositions.json +43 -0
  208. lairs-0.1.0/lairs/lexicons/pub/layers/resource/listTemplates.json +82 -0
  209. lairs-0.1.0/lairs/lexicons/pub/layers/resource/template.json +90 -0
  210. lairs-0.1.0/lairs/lexicons/pub/layers/resource/templateComposition.json +54 -0
  211. lairs-0.1.0/lairs/lexicons/pub/layers/segmentation/defs.json +71 -0
  212. lairs-0.1.0/lairs/lexicons/pub/layers/segmentation/getSegmentation.json +30 -0
  213. lairs-0.1.0/lairs/lexicons/pub/layers/segmentation/listSegmentations.json +42 -0
  214. lairs-0.1.0/lairs/lexicons/pub/layers/segmentation/segmentation.json +72 -0
  215. lairs-0.1.0/lairs/media/__init__.py +29 -0
  216. lairs-0.1.0/lairs/media/anchors.py +381 -0
  217. lairs-0.1.0/lairs/media/audio.py +214 -0
  218. lairs-0.1.0/lairs/media/neural.py +295 -0
  219. lairs-0.1.0/lairs/media/resolve.py +312 -0
  220. lairs-0.1.0/lairs/media/video.py +289 -0
  221. lairs-0.1.0/lairs/py.typed +0 -0
  222. lairs-0.1.0/lairs/records/__init__.py +55 -0
  223. lairs-0.1.0/lairs/records/_generated/.gitkeep +0 -0
  224. lairs-0.1.0/lairs/records/_generated/__init__.py +42 -0
  225. lairs-0.1.0/lairs/records/_generated/alignment.py +126 -0
  226. lairs-0.1.0/lairs/records/_generated/annotation.py +424 -0
  227. lairs-0.1.0/lairs/records/_generated/changelog.py +144 -0
  228. lairs-0.1.0/lairs/records/_generated/corpus.py +319 -0
  229. lairs-0.1.0/lairs/records/_generated/defs.py +1075 -0
  230. lairs-0.1.0/lairs/records/_generated/eprint.py +445 -0
  231. lairs-0.1.0/lairs/records/_generated/expression.py +127 -0
  232. lairs-0.1.0/lairs/records/_generated/graph.py +333 -0
  233. lairs-0.1.0/lairs/records/_generated/judgment.py +506 -0
  234. lairs-0.1.0/lairs/records/_generated/media.py +302 -0
  235. lairs-0.1.0/lairs/records/_generated/ontology.py +197 -0
  236. lairs-0.1.0/lairs/records/_generated/persona.py +122 -0
  237. lairs-0.1.0/lairs/records/_generated/resource.py +474 -0
  238. lairs-0.1.0/lairs/records/_generated/segmentation.py +129 -0
  239. lairs-0.1.0/lairs/records/blobref.py +80 -0
  240. lairs-0.1.0/lairs/records/views.py +123 -0
  241. lairs-0.1.0/lairs/store/__init__.py +32 -0
  242. lairs-0.1.0/lairs/store/arrow.py +596 -0
  243. lairs-0.1.0/lairs/store/blobcache.py +228 -0
  244. lairs-0.1.0/lairs/store/pool.py +255 -0
  245. lairs-0.1.0/lairs/store/repository.py +595 -0
  246. lairs-0.1.0/lairs/tui/__init__.py +93 -0
  247. lairs-0.1.0/lairs/tui/app.py +193 -0
  248. lairs-0.1.0/lairs/tui/browse.py +234 -0
  249. lairs-0.1.0/lairs/tui/query.py +555 -0
  250. lairs-0.1.0/lairs/tui/registry.py +75 -0
  251. lairs-0.1.0/lairs/tui/screens/__init__.py +9 -0
  252. lairs-0.1.0/lairs/tui/screens/browse.py +200 -0
  253. lairs-0.1.0/lairs/tui/screens/explore.py +204 -0
  254. lairs-0.1.0/lairs/tui/screens/query.py +238 -0
  255. lairs-0.1.0/lairs/tui/styles.tcss +219 -0
  256. lairs-0.1.0/lairs/tui/views.py +964 -0
  257. lairs-0.1.0/lairs/tui/viz.py +967 -0
  258. lairs-0.1.0/mkdocs.yml +116 -0
  259. lairs-0.1.0/pyproject.toml +211 -0
  260. lairs-0.1.0/tests/_codegen/test___init__.py +27 -0
  261. lairs-0.1.0/tests/_codegen/test_emit.py +186 -0
  262. lairs-0.1.0/tests/_codegen/test_manifest.py +53 -0
  263. lairs-0.1.0/tests/_codegen/test_pipeline.py +223 -0
  264. lairs-0.1.0/tests/_codegen/test_schema_to_spec.py +370 -0
  265. lairs-0.1.0/tests/atproto/test___init__.py +46 -0
  266. lairs-0.1.0/tests/atproto/test__car.py +55 -0
  267. lairs-0.1.0/tests/atproto/test_appview.py +137 -0
  268. lairs-0.1.0/tests/atproto/test_auth.py +319 -0
  269. lairs-0.1.0/tests/atproto/test_blobs.py +152 -0
  270. lairs-0.1.0/tests/atproto/test_firehose.py +283 -0
  271. lairs-0.1.0/tests/atproto/test_identity.py +257 -0
  272. lairs-0.1.0/tests/atproto/test_pds.py +755 -0
  273. lairs-0.1.0/tests/author/test___init__.py +42 -0
  274. lairs-0.1.0/tests/author/test_builders.py +325 -0
  275. lairs-0.1.0/tests/author/test_publish.py +1082 -0
  276. lairs-0.1.0/tests/conftest.py +405 -0
  277. lairs-0.1.0/tests/data/test___init__.py +42 -0
  278. lairs-0.1.0/tests/data/test_corpus.py +466 -0
  279. lairs-0.1.0/tests/data/test_dataset.py +272 -0
  280. lairs-0.1.0/tests/data/test_features.py +144 -0
  281. lairs-0.1.0/tests/discovery/test___init__.py +29 -0
  282. lairs-0.1.0/tests/discovery/test_accelerator.py +193 -0
  283. lairs-0.1.0/tests/discovery/test_actor.py +281 -0
  284. lairs-0.1.0/tests/discovery/test_cards.py +101 -0
  285. lairs-0.1.0/tests/discovery/test_federated.py +179 -0
  286. lairs-0.1.0/tests/discovery/test_index.py +137 -0
  287. lairs-0.1.0/tests/discovery/test_ingest.py +304 -0
  288. lairs-0.1.0/tests/discovery/test_links.py +102 -0
  289. lairs-0.1.0/tests/discovery/test_models.py +68 -0
  290. lairs-0.1.0/tests/discovery/test_query.py +104 -0
  291. lairs-0.1.0/tests/discovery/test_summary.py +222 -0
  292. lairs-0.1.0/tests/integrations/codecs/test___init__.py +67 -0
  293. lairs-0.1.0/tests/integrations/codecs/test_brat.py +307 -0
  294. lairs-0.1.0/tests/integrations/codecs/test_conllu.py +334 -0
  295. lairs-0.1.0/tests/integrations/hf/test___init__.py +42 -0
  296. lairs-0.1.0/tests/integrations/hf/test_datasets.py +301 -0
  297. lairs-0.1.0/tests/integrations/hf/test_hub.py +374 -0
  298. lairs-0.1.0/tests/integrations/kb/test___init__.py +49 -0
  299. lairs-0.1.0/tests/integrations/kb/test_glazing.py +278 -0
  300. lairs-0.1.0/tests/integrations/kb/test_reconciliation.py +332 -0
  301. lairs-0.1.0/tests/integrations/kb/test_wikidata.py +340 -0
  302. lairs-0.1.0/tests/integrations/test___init__.py +28 -0
  303. lairs-0.1.0/tests/integrations/test_ports.py +56 -0
  304. lairs-0.1.0/tests/integrations/test_registry.py +123 -0
  305. lairs-0.1.0/tests/integrations/test_tfdata.py +220 -0
  306. lairs-0.1.0/tests/integrations/test_torch.py +274 -0
  307. lairs-0.1.0/tests/integrations/test_tracking.py +211 -0
  308. lairs-0.1.0/tests/integrations/test_webdataset.py +314 -0
  309. lairs-0.1.0/tests/media/test___init__.py +36 -0
  310. lairs-0.1.0/tests/media/test_anchors.py +302 -0
  311. lairs-0.1.0/tests/media/test_audio.py +123 -0
  312. lairs-0.1.0/tests/media/test_neural.py +165 -0
  313. lairs-0.1.0/tests/media/test_resolve.py +185 -0
  314. lairs-0.1.0/tests/media/test_video.py +195 -0
  315. lairs-0.1.0/tests/pds/README.md +50 -0
  316. lairs-0.1.0/tests/pds/docker-compose.yml +43 -0
  317. lairs-0.1.0/tests/records/_generated/test___init__.py +169 -0
  318. lairs-0.1.0/tests/records/test___init__.py +56 -0
  319. lairs-0.1.0/tests/records/test_blobref.py +99 -0
  320. lairs-0.1.0/tests/records/test_views.py +147 -0
  321. lairs-0.1.0/tests/store/test___init__.py +26 -0
  322. lairs-0.1.0/tests/store/test_arrow.py +290 -0
  323. lairs-0.1.0/tests/store/test_blobcache.py +120 -0
  324. lairs-0.1.0/tests/store/test_pool.py +113 -0
  325. lairs-0.1.0/tests/store/test_repository.py +219 -0
  326. lairs-0.1.0/tests/test___init__.py +71 -0
  327. lairs-0.1.0/tests/test__aturi.py +29 -0
  328. lairs-0.1.0/tests/test__types.py +23 -0
  329. lairs-0.1.0/tests/test_cli.py +1241 -0
  330. lairs-0.1.0/tests/tui/conftest.py +462 -0
  331. lairs-0.1.0/tests/tui/test_app.py +422 -0
  332. lairs-0.1.0/tests/tui/test_browse.py +601 -0
  333. lairs-0.1.0/tests/tui/test_interaction.py +358 -0
  334. lairs-0.1.0/tests/tui/test_query.py +368 -0
  335. lairs-0.1.0/tests/tui/test_viz.py +438 -0
  336. lairs-0.1.0/uv.lock +4639 -0
@@ -0,0 +1,109 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ workflow_dispatch:
8
+
9
+ # cancel superseded runs on the same ref (a new push to a PR supersedes the old).
10
+ concurrency:
11
+ group: ci-${{ github.workflow }}-${{ github.ref }}
12
+ cancel-in-progress: true
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ env:
18
+ # pin the Python the whole workflow resolves against.
19
+ UV_PYTHON: "3.14"
20
+
21
+ jobs:
22
+ # static gates: formatting, lint, types, the Any/object ban, codegen drift,
23
+ # and a strict docs build. no docker, so this finishes fast and fails early.
24
+ quality:
25
+ name: Quality gates
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+
30
+ - name: Install uv
31
+ uses: astral-sh/setup-uv@v5
32
+ with:
33
+ enable-cache: true
34
+
35
+ - name: Install Python ${{ env.UV_PYTHON }}
36
+ run: uv python install ${{ env.UV_PYTHON }}
37
+
38
+ - name: Sync dependencies (dev + docs)
39
+ run: uv sync --frozen --group docs
40
+
41
+ - name: Ruff format
42
+ run: uv run ruff format --check lairs tests
43
+
44
+ - name: Ruff lint
45
+ run: uv run ruff check lairs tests
46
+
47
+ - name: Install TensorFlow nightly
48
+ # TensorFlow ships no stable cp314 wheel yet (the tf extra markers it out
49
+ # of the locked env), so the nightly provides one. Installing it lets ty
50
+ # resolve `import tensorflow` in the tfdata exporter. decord and
51
+ # label-studio-sdk have no cp314 wheel at all and remain unexercised.
52
+ run: uv pip install tf-nightly
53
+
54
+ - name: Type check (ty)
55
+ run: uv run ty check --error-on-warning
56
+
57
+ - name: Forbid Any in annotations
58
+ # `Any` is the unsound escape hatch; ruff ANN401 (part of the ALL
59
+ # ruleset above) flags it in annotation positions precisely, with no
60
+ # docstring false positives. sound `object` is allowed: it must be
61
+ # narrowed before use, and the ALL ruleset itself requires annotating
62
+ # ignored *args/**kwargs, for which `object` is the only sound choice.
63
+ run: uv run ruff check lairs tests --select ANN401
64
+
65
+ - name: Generated-model drift gate
66
+ run: uv run lairs gen --check
67
+
68
+ - name: Build documentation (strict)
69
+ run: uv run --group docs mkdocs build --strict
70
+
71
+ # the full suite, including every integration test. the pds_server fixture
72
+ # starts a real bluesky PDS through docker compose (docker and compose v2 are
73
+ # preinstalled on the runner), so --run-integration exercises the genuine
74
+ # read/write path rather than skipping it.
75
+ test:
76
+ name: Test suite (all tests, with Docker PDS)
77
+ runs-on: ubuntu-latest
78
+ steps:
79
+ - uses: actions/checkout@v4
80
+
81
+ - name: Install uv
82
+ uses: astral-sh/setup-uv@v5
83
+ with:
84
+ enable-cache: true
85
+
86
+ - name: Install Python ${{ env.UV_PYTHON }}
87
+ run: uv python install ${{ env.UV_PYTHON }}
88
+
89
+ - name: Sync dependencies (dev group with every installable extra)
90
+ run: uv sync --frozen
91
+
92
+ - name: Install TensorFlow nightly
93
+ # no stable cp314 wheel yet; the nightly runs the tfdata exporter tests
94
+ # rather than skipping them. decord and label-studio-sdk have no cp314
95
+ # wheel at all, so a small number of their tests skip cleanly.
96
+ run: uv pip install tf-nightly
97
+
98
+ - name: Confirm Docker is available
99
+ run: |
100
+ docker version
101
+ docker compose version
102
+
103
+ - name: Pre-pull the PDS image
104
+ # warm the integration container so the health check does not race a
105
+ # cold image pull. the fixture manages compose lifecycle per session.
106
+ run: docker compose -f tests/pds/docker-compose.yml pull
107
+
108
+ - name: Run the full test suite
109
+ run: uv run pytest --run-integration -v
@@ -0,0 +1,70 @@
1
+ name: Docs
2
+
3
+ # build the documentation and publish it to GitHub Pages. the site is served at
4
+ # https://layers.pub/lairs/: the layers-pub organization's Pages custom apex
5
+ # domain (layers.pub) serves each project repository's Pages at /<repo>/, so the
6
+ # lairs project site lands at /lairs/. no per-repo CNAME is needed; the project
7
+ # inherits the organization's domain.
8
+ on:
9
+ push:
10
+ branches: [main]
11
+ paths:
12
+ - "docs/**"
13
+ - "mkdocs.yml"
14
+ - "lairs/**" # docstrings feed the API reference via mkdocstrings
15
+ - "pyproject.toml"
16
+ - ".github/workflows/docs.yml"
17
+ workflow_dispatch:
18
+
19
+ permissions:
20
+ contents: read
21
+
22
+ # one Pages deployment at a time; let an in-flight deploy finish rather than
23
+ # cancelling it.
24
+ concurrency:
25
+ group: pages
26
+ cancel-in-progress: false
27
+
28
+ env:
29
+ UV_PYTHON: "3.14"
30
+
31
+ jobs:
32
+ build:
33
+ name: Build site
34
+ runs-on: ubuntu-latest
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+
38
+ - name: Install uv
39
+ uses: astral-sh/setup-uv@v5
40
+ with:
41
+ enable-cache: true
42
+
43
+ - name: Install Python ${{ env.UV_PYTHON }}
44
+ run: uv python install ${{ env.UV_PYTHON }}
45
+
46
+ - name: Sync docs dependencies
47
+ run: uv sync --frozen --group docs
48
+
49
+ - name: Build the site (strict)
50
+ run: uv run --group docs mkdocs build --strict
51
+
52
+ - name: Upload the Pages artifact
53
+ uses: actions/upload-pages-artifact@v3
54
+ with:
55
+ path: site
56
+
57
+ deploy:
58
+ name: Deploy to GitHub Pages
59
+ needs: build
60
+ runs-on: ubuntu-latest
61
+ environment:
62
+ name: github-pages
63
+ url: ${{ steps.deployment.outputs.page_url }}
64
+ permissions:
65
+ pages: write
66
+ id-token: write
67
+ steps:
68
+ - name: Deploy
69
+ id: deployment
70
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,169 @@
1
+ name: Release
2
+
3
+ # tags shaped like v0.1.0 cut a release: verify, build, publish to PyPI via
4
+ # Trusted Publishing, and create the GitHub release.
5
+ on:
6
+ push:
7
+ tags: ["v*"]
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ env:
14
+ UV_PYTHON: "3.14"
15
+
16
+ jobs:
17
+ # gate the release on the same checks CI runs, so a tag can never publish a
18
+ # red build. the full suite (including the Docker PDS integration tests) runs
19
+ # here too.
20
+ verify:
21
+ name: Verify before release
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - uses: actions/checkout@v4
25
+
26
+ - name: Install uv
27
+ uses: astral-sh/setup-uv@v5
28
+ with:
29
+ enable-cache: true
30
+
31
+ - name: Install Python ${{ env.UV_PYTHON }}
32
+ run: uv python install ${{ env.UV_PYTHON }}
33
+
34
+ - name: Sync dependencies (dev + docs)
35
+ run: uv sync --frozen --group docs
36
+
37
+ - name: Ruff format
38
+ run: uv run ruff format --check lairs tests
39
+
40
+ - name: Ruff lint
41
+ run: uv run ruff check lairs tests
42
+
43
+ - name: Install TensorFlow nightly
44
+ # no stable cp314 wheel yet; the nightly lets ty resolve tensorflow and
45
+ # runs the tfdata exporter tests rather than skipping them.
46
+ run: uv pip install tf-nightly
47
+
48
+ - name: Type check (ty)
49
+ run: uv run ty check --error-on-warning
50
+
51
+ - name: Generated-model drift gate
52
+ run: uv run lairs gen --check
53
+
54
+ - name: Build documentation (strict)
55
+ run: uv run --group docs mkdocs build --strict
56
+
57
+ - name: Pre-pull the PDS image
58
+ run: docker compose -f tests/pds/docker-compose.yml pull
59
+
60
+ - name: Run the full test suite
61
+ run: uv run pytest --run-integration
62
+
63
+ # build the sdist and wheel once and hand them to every downstream job.
64
+ build:
65
+ name: Build distributions
66
+ needs: verify
67
+ runs-on: ubuntu-latest
68
+ steps:
69
+ - uses: actions/checkout@v4
70
+
71
+ - name: Install uv
72
+ uses: astral-sh/setup-uv@v5
73
+ with:
74
+ enable-cache: true
75
+
76
+ - name: Install Python ${{ env.UV_PYTHON }}
77
+ run: uv python install ${{ env.UV_PYTHON }}
78
+
79
+ - name: Build sdist and wheel
80
+ run: uv build
81
+
82
+ - name: Check distribution metadata
83
+ run: uvx twine check dist/*
84
+
85
+ - name: Confirm the built version matches the tag
86
+ if: startsWith(github.ref, 'refs/tags/v')
87
+ run: |
88
+ set -euo pipefail
89
+ tag_version="${GITHUB_REF_NAME#v}"
90
+ built=$(ls dist/lairs-*.tar.gz | sed -E 's#.*/lairs-(.*)\.tar\.gz#\1#')
91
+ if [ "$tag_version" != "$built" ]; then
92
+ echo "::error::tag $GITHUB_REF_NAME does not match built version $built"
93
+ exit 1
94
+ fi
95
+ echo "tag and built version agree: $built"
96
+
97
+ - name: Upload distributions
98
+ uses: actions/upload-artifact@v4
99
+ with:
100
+ name: dist
101
+ path: dist/
102
+ if-no-files-found: error
103
+
104
+ # publish to PyPI with Trusted Publishing (OIDC): no token is stored. the
105
+ # `pypi` environment scopes the trusted publisher and gates the step on any
106
+ # protection rules you add to it.
107
+ pypi:
108
+ name: Publish to PyPI
109
+ needs: build
110
+ if: startsWith(github.ref, 'refs/tags/v')
111
+ runs-on: ubuntu-latest
112
+ environment:
113
+ name: pypi
114
+ url: https://pypi.org/project/lairs/
115
+ permissions:
116
+ id-token: write
117
+ steps:
118
+ - name: Download distributions
119
+ uses: actions/download-artifact@v4
120
+ with:
121
+ name: dist
122
+ path: dist/
123
+
124
+ - name: Publish
125
+ uses: pypa/gh-action-pypi-publish@release/v1
126
+
127
+ # create the GitHub release from the tag, with the changelog section as notes
128
+ # and the built artifacts attached.
129
+ github-release:
130
+ name: GitHub release
131
+ needs: [build, pypi]
132
+ if: startsWith(github.ref, 'refs/tags/v')
133
+ runs-on: ubuntu-latest
134
+ permissions:
135
+ contents: write
136
+ steps:
137
+ - uses: actions/checkout@v4
138
+
139
+ - name: Download distributions
140
+ uses: actions/download-artifact@v4
141
+ with:
142
+ name: dist
143
+ path: dist/
144
+
145
+ - name: Extract the changelog section for this tag
146
+ run: |
147
+ set -euo pipefail
148
+ version="${GITHUB_REF_NAME#v}"
149
+ awk -v v="$version" '
150
+ $0 ~ "^## \\[" v "\\]" { flag = 1; next }
151
+ flag && /^## \[/ { exit }
152
+ flag { print }
153
+ ' CHANGELOG.md > release-notes.md
154
+ if [ ! -s release-notes.md ]; then
155
+ echo "See [CHANGELOG.md](CHANGELOG.md)." > release-notes.md
156
+ fi
157
+
158
+ - name: Create the release
159
+ uses: softprops/action-gh-release@v2
160
+ with:
161
+ body_path: release-notes.md
162
+ files: dist/*
163
+ fail_on_unmatched_files: true
164
+
165
+ # documentation is built and deployed to GitHub Pages by the dedicated Docs
166
+ # workflow (.github/workflows/docs.yml) on every push to main. the release
167
+ # commit (version bump and changelog) lands on main before the tag, so the
168
+ # published site at https://layers.pub/lairs/ is already current by release
169
+ # time. nothing to deploy here.
lairs-0.1.0/.gitignore ADDED
@@ -0,0 +1,39 @@
1
+ # virtual environments
2
+ .venv/
3
+ venv/
4
+
5
+ # python bytecode and caches
6
+ __pycache__/
7
+ *.pyc
8
+ *.pyo
9
+
10
+ # tool caches
11
+ .ruff_cache/
12
+ .ty_cache/
13
+ .pytest_cache/
14
+ .mypy_cache/
15
+ .coverage
16
+ .coverage.*
17
+ htmlcov/
18
+
19
+ # build artifacts
20
+ build/
21
+ dist/
22
+ *.egg-info/
23
+
24
+ # data and cache directories
25
+ /data/
26
+ .lairs/
27
+ *.parquet
28
+ blobs/
29
+
30
+ # dev notes and local-only design doc
31
+ notes/
32
+ PLAN.md
33
+ CLAUDE.md
34
+
35
+ # OS cruft
36
+ .DS_Store
37
+
38
+ # mkdocs build output
39
+ /site/
@@ -0,0 +1,65 @@
1
+ # Changelog
2
+
3
+ All notable changes to `lairs` are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-06-25
11
+
12
+ The first public release. `lairs` is a read/write dataset client for the
13
+ [Layers](https://github.com/layers-pub) format on the AT Protocol: the mental
14
+ model is `datasets` and `git` for decentralised linguistic annotation. It is
15
+ built on [didactic](https://github.com/panproto/didactic) and
16
+ [panproto](https://github.com/panproto/phrom); every structured value is a
17
+ didactic model.
18
+
19
+ ### Added
20
+
21
+ - **Generated record models.** Typed models for the 26 `pub.layers.*` record
22
+ types, generated from the vendored Layers lexicons, with a content-addressed
23
+ `BlobRef` value type and a drift gate (`lairs gen --check`).
24
+ - **ATProto access layer.** Read records and whole repositories from a Personal
25
+ Data Server over XRPC, decode CAR/DAG-CBOR commits, resolve handles and DIDs,
26
+ and follow the firehose with cursor-based reconnect.
27
+ - **Schema-aware local store.** A panproto-backed, git-like repository where a
28
+ corpus snapshot is a commit and a dataset version is a tag, with collision-free
29
+ record files, a deletion/tombstone path, and revision-to-revision diffs. An
30
+ Arrow/Parquet materialiser flattens records and polymorphic anchors into typed
31
+ columns.
32
+ - **Dataset and corpus API.** A HuggingFace-`datasets`-like surface with lazy and
33
+ streaming `Dataset`, feature derivation, and a `Corpus` scoped to its
34
+ membership records with train/dev/test split accessors.
35
+ - **Authoring and publishing.** Validated-by-construction builders, blob upload,
36
+ and dependency-ordered bulk publishing to the authenticated user's own
37
+ repository, with an idempotent re-publish that is a no-op for unchanged
38
+ records (including blob-bearing media, expression, and persona records).
39
+ - **Media layer.** On-demand resolution of audio, video, and time-series signals
40
+ behind injected fetcher and content-addressed cache ports, with anchor
41
+ resolution over the full anchor union (text, token, temporal, spatio-temporal,
42
+ page, and external targets).
43
+ - **Dataset discovery.** Crawl the Layers network for corpora, maintain a local
44
+ searchable index with a DuckDB query accelerator, tail the firehose to keep the
45
+ index fresh (including deletions), and diff index revisions.
46
+ - **Format codecs.** brat stand-off and CoNLL-U import/export, discoverable
47
+ through entry points.
48
+ - **Framework exporters.** HuggingFace `datasets` and Hub push/pull, PyTorch
49
+ (map-style and worker-sharded iterable), `tf.data`, and WebDataset exporters,
50
+ each behind an optional extra.
51
+ - **Knowledge-base connectors.** Wikidata, OpenRefine reconciliation, and Glazing
52
+ connectors behind a common port, with experiment-tracking provenance for
53
+ MLflow and Weights & Biases.
54
+ - **Terminal explorer.** `lairs tui`, a colourful three-tab TUI to Explore the
55
+ discovery index, Browse every record type in a repository with model-driven,
56
+ view-switched visualisations (CoNLL-U grids, dependency trees, span overlays,
57
+ judgment distributions, alignments, and more), and Query materialised data with
58
+ SQL, a KWIC concordance, and a CQL token-pattern language.
59
+ - **Command-line interface.** The `lairs` command for vendoring lexicons,
60
+ regenerating models, pulling and materialising corpora, publishing, inspecting
61
+ repositories, discovering datasets, building and searching the index, managing
62
+ sessions, and launching the explorer.
63
+
64
+ [Unreleased]: https://github.com/layers-pub/lairs/compare/v0.1.0...HEAD
65
+ [0.1.0]: https://github.com/layers-pub/lairs/releases/tag/v0.1.0
@@ -0,0 +1,133 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, caste, color, religion, or sexual
10
+ identity and orientation.
11
+
12
+ We pledge to act and interact in ways that contribute to an open, welcoming,
13
+ diverse, inclusive, and healthy community.
14
+
15
+ ## Our Standards
16
+
17
+ Examples of behavior that contributes to a positive environment for our
18
+ community include:
19
+
20
+ - Demonstrating empathy and kindness toward other people
21
+ - Being respectful of differing opinions, viewpoints, and experiences
22
+ - Giving and gracefully accepting constructive feedback
23
+ - Accepting responsibility and apologizing to those affected by our mistakes,
24
+ and learning from the experience
25
+ - Focusing on what is best not just for us as individuals, but for the overall
26
+ community
27
+
28
+ Examples of unacceptable behavior include:
29
+
30
+ - The use of sexualized language or imagery, and sexual attention or advances of
31
+ any kind
32
+ - Trolling, insulting or derogatory comments, and personal or political attacks
33
+ - Public or private harassment
34
+ - Publishing others' private information, such as a physical or email address,
35
+ without their explicit permission
36
+ - Other conduct which could reasonably be considered inappropriate in a
37
+ professional setting
38
+
39
+ ## Enforcement Responsibilities
40
+
41
+ Community leaders are responsible for clarifying and enforcing our standards of
42
+ acceptable behavior and will take appropriate and fair corrective action in
43
+ response to any behavior that they deem inappropriate, threatening, offensive,
44
+ or harmful.
45
+
46
+ Community leaders have the right and responsibility to remove, edit, or reject
47
+ comments, commits, code, wiki edits, issues, and other contributions that are
48
+ not aligned to this Code of Conduct, and will communicate reasons for moderation
49
+ decisions when appropriate.
50
+
51
+ ## Scope
52
+
53
+ This Code of Conduct applies within all community spaces, and also applies when
54
+ an individual is officially representing the community in public spaces.
55
+ Examples of representing our community include using an official email address,
56
+ posting via an official social media account, or acting as an appointed
57
+ representative at an online or offline event.
58
+
59
+ ## Enforcement
60
+
61
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
62
+ reported to the community leaders responsible for enforcement at
63
+ aaronstevenwhite@gmail.com. All complaints will be reviewed and investigated
64
+ promptly and fairly.
65
+
66
+ All community leaders are obligated to respect the privacy and security of the
67
+ reporter of any incident.
68
+
69
+ ## Enforcement Guidelines
70
+
71
+ Community leaders will follow these Community Impact Guidelines in determining
72
+ the consequences for any action they deem in violation of this Code of Conduct:
73
+
74
+ ### 1. Correction
75
+
76
+ **Community Impact**: Use of inappropriate language or other behavior deemed
77
+ unprofessional or unwelcome in the community.
78
+
79
+ **Consequence**: A private, written warning from community leaders, providing
80
+ clarity around the nature of the violation and an explanation of why the
81
+ behavior was inappropriate. A public apology may be requested.
82
+
83
+ ### 2. Warning
84
+
85
+ **Community Impact**: A violation through a single incident or series of
86
+ actions.
87
+
88
+ **Consequence**: A warning with consequences for continued behavior. No
89
+ interaction with the people involved, including unsolicited interaction with
90
+ those enforcing the Code of Conduct, for a specified period of time. This
91
+ includes avoiding interactions in community spaces as well as external channels
92
+ like social media. Violating these terms may lead to a temporary or permanent
93
+ ban.
94
+
95
+ ### 3. Temporary Ban
96
+
97
+ **Community Impact**: A serious violation of community standards, including
98
+ sustained inappropriate behavior.
99
+
100
+ **Consequence**: A temporary ban from any sort of interaction or public
101
+ communication with the community for a specified period of time. No public or
102
+ private interaction with the people involved, including unsolicited interaction
103
+ with those enforcing the Code of Conduct, is allowed during this period.
104
+ Violating these terms may lead to a permanent ban.
105
+
106
+ ### 4. Permanent Ban
107
+
108
+ **Community Impact**: Demonstrating a pattern of violation of community
109
+ standards, including sustained inappropriate behavior, harassment of an
110
+ individual, or aggression toward or disparagement of classes of individuals.
111
+
112
+ **Consequence**: A permanent ban from any sort of public interaction within the
113
+ community.
114
+
115
+ ## Attribution
116
+
117
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118
+ version 2.1, available at
119
+ [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
120
+
121
+ Community Impact Guidelines were inspired by
122
+ [Mozilla's code of conduct enforcement ladder][mozilla].
123
+
124
+ [homepage]: https://www.contributor-covenant.org
125
+ [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
126
+ [mozilla]: https://github.com/mozilla/diversity
127
+
128
+ For answers to common questions about this code of conduct, see the FAQ at
129
+ [https://www.contributor-covenant.org/faq][faq]. Translations are available at
130
+ [https://www.contributor-covenant.org/translations][translations].
131
+
132
+ [faq]: https://www.contributor-covenant.org/faq
133
+ [translations]: https://www.contributor-covenant.org/translations