diff --git a/.gitignore b/.gitignore index 408b27f..6fb49b8 100644 --- a/.gitignore +++ b/.gitignore @@ -104,3 +104,6 @@ venv.bak/ # mypy .mypy_cache/ + +.vscode +.idea diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..211de99 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,51 @@ +--- +fail_fast: true +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.2.1 + hooks: + - id: check-ast + - id: check-symlinks + - id: check-executables-have-shebangs + - id: check-merge-conflict + - id: check-json + - id: check-yaml + - id: detect-private-key + - id: double-quote-string-fixer + - id: trailing-whitespace + - id: no-commit-to-branch # No (direct) commits to master + - repo: https://github.com/asottile/add-trailing-comma + rev: v1.0.0 + hooks: + - id: add-trailing-comma + - repo: https://github.com/pre-commit/mirrors-isort + rev: v4.3.18 + hooks: + - id: isort + - repo: https://github.com/Lucas-C/pre-commit-hooks + rev: v1.1.6 + hooks: + - id: forbid-crlf + files: \.md$ + - id: remove-crlf + files: \.md$ + - repo: local + hooks: + - id: lint + name: tox lint + entry: tox -e lint + language: system + - id: doclint + name: tox doclint + entry: tox -e doclint + language: system + - id: mypy + name: tox mypy + entry: tox -e mypy + language: system + types: [python] + - id: tests + name: tox tests + entry: tox -e tests + language: system + types: [python, yaml] diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..386fdfc --- /dev/null +++ b/.travis.yml @@ -0,0 +1,41 @@ +dist: xenial +env: + global: + - CC_TEST_REPORTER_ID=$TEST_REPORTER_ID +language: python +os: +- linux +python: +- '3.7' +install: +- python -m pip install -U pip setuptools pipenv +- pipenv install --dev +- python -m pip install -e . +before_script: +- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 + > ./cc-test-reporter +- chmod +x ./cc-test-reporter +- "./cc-test-reporter before-build" +script: +- tox -e lint +- tox -e isort +- tox -e mypy +- tox -e tests +after_script: +- coverage xml -o coverage.xml +- "./cc-test-reporter after-build --coverage-input-type coverage.py --exit-code $TRAVIS_TEST_RESULT" +deploy: +- provider: script + script: ci-scripts/semantic-release.sh + on: + branch: master +notifications: + slack: + rooms: + - secure: XU8s7FeivT74v46HKBHxCeAx/RA+cbVzufJjAtAVvAcuz1/cCySUjLWJCHzsSjPBoff7BKxPO2Sxlxb+FmgTGKEX48rqJM5ZAR3IrVeDseix64030ANOd3KRvnZYTPvqF9ovtV6d0GhbO/BAc4XNfx47RsG31LLRQcZnaAL2x7J2C1KsvmMG1ckQoYVZJgxQszUZm4NTlGRjiCd2EbZIfdeo33Wm0vPSgHprSe8z0Ov0sk5SLDJRSZh1z6TrchfxmXZLmi19oOB+vkEMJtvyDgxF1x/tT3aMmD/jB9qt7RR+11RigLTVrq5ANKQ10NFE+TsOd8ZwjZ3Ng1Ont2HmdExltNsI0goynx1nKlaHOnDmJ8xOp/XF1k8EsVkyWFCTywjZGIV2nNzC60qd4q719l7gnsV11nnaEc2IrfREV43Hq3C5CfhkLwZCm77ePSW0ckzFN1iucjvh8SCPf75p+WwtegAgNHB+jjHWLEA1R1/kcYwHHL2w4MLPxt5y0DdwMxjGYNWW1Eys7rpK6U1qSqhe6z/3b+YRM+YXekvojEnxz9KU51ZbqxqPplkTeiRmYW+GYiks7MXdOwcSFrTDcttEJY/xd9zN71rWNzTmAfzTJgSI51JJpq13uJuUJzTqTXpT7lI5nDjnl2dUZyrQzdUyqzbIoqttFW2TOT8hzKY= + on_success: always # change: send a notification when the build status changes. + on_failure: always # always: always send a notification. + template: + - "Repo `%{repository_slug}` *%{result}* build (<%{build_url}|#%{build_number}>) for commit (<%{compare_url}|%{commit}>) on branch `%{branch}`." + - "Execution time: *%{duration}*" + - "Message: %{message}" diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..4bc89c8 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,3 @@ +include README.md +include CHANGELOG.md +recursive-exclude tests * diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f50b11c --- /dev/null +++ b/Makefile @@ -0,0 +1,99 @@ +.PHONY: help clean clean-pyc clean-build list test test-dbg test-cov test-all coverage docs release sdist install install-dev install-ci lint mypy isort isort-check + +project-name = pycon_schemas + +version-var := "__version__ = " +version-string := $(shell grep $(version-var) $(project-name)/version.py) +version := $(subst __version__ = ,,$(version-string)) + +help: + @echo "install - install" + @echo "install-dev - install also development dependencies" + @echo "clean - clean all below" + @echo "clean-build - remove build artifacts" + @echo "clean-pyc - remove Python file artifacts" + @echo "clean-tox - clean tox cache" + @echo "lint - check style with flake8" + @echo "test - run tests quickly with the default Python" + @echo "test-cov - run tests with the default Python and report coverage" + @echo "test-dbg - run tests and debug with pdb" + @echo "develop - run tests in loop mode" + @echo "deploy - deploy" + @echo "mypy - check type hinting with mypy" + @echo "isort - sort imports" + @echo "isort-check - check if your imports are correctly sorted" + @echo "build - create the distribution package" + @echo "release - package a release in wheel and tarball, requires twine" + +install: + python -m pip install pipenv + pipenv install + python -m pip install . + +install-ci: + python -m pip install pipenv + pipenv install --dev + python -m pip install -e . + +install-dev: install-ci + pre-commit install + +clean: clean-build clean-pyc clean-caches + +clean-build: + rm -fr build/ + rm -fr dist/ + rm -fr .eggs/ + rm -fr *.egg-info + rm -fr *.spec + +clean-pyc: + pyclean $(project-name) + find . -name '*~' -exec rm -f {} + + find . -name __pycache__ -exec rm -rf {} + + find . -name '*.log*' -delete + find . -name '*_cache' -exec rm -rf {} + + find . -name '*.egg-info' -exec rm -rf {} + + +clean-caches: + rm -rf .tox + rm -rf .pytest_cache + +testloop: + pytest --color=yes -s -f $(project-name) + +lint: + tox -e lint + +test: + tox -e tests + +mypy: + tox -e mypy + +isort-check: + tox -e isort + +isort: + isort -rc $(project-name) + +test-cov: + py.test --cov-report term-missing --cov=$(project-name) + +test-dbg: + py.test --pdb + +develop: + py.test --color=yes -f + +coverage: + pytest --cov=hansel + coverage report -m + +build: + python setup.py sdist bdist_wheel + +pypi: + twine upload dist/* + +release: clean build pypi diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..406046b --- /dev/null +++ b/Pipfile @@ -0,0 +1,30 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +jsonschema = "==3.1.1" + +[dev-packages] +flake8 = "*" +flake8-bugbear = "*" +autopep8 = "*" +pre-commit = "*" +pytest = "*" +pytest-cov = "*" +pytest-xdist = "*" +pytest-only = "*" +watchdog = "*" +mypy = "*" +isort = "*" +tox = ">=3.13.2" +coverage = "*" +wily = "*" +jsonschema = "==3.0.2" +pyclean-py = "*" +pytest-mock = "*" +rope = "*" +twine = "*" +pydocstyle = "*" +tox-pipenv-install = "*" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..37b6f51 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,719 @@ +{ + "_meta": { + "hash": { + "sha256": "7158de61acc8a2cb9008d56482c9221c42888f05e62831a55ed3dd29f98046c7" + }, + "pipfile-spec": 6, + "requires": {}, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.python.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "attrs": { + "hashes": [ + "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", + "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" + ], + "version": "==19.3.0" + }, + "importlib-metadata": { + "hashes": [ + "sha256:aa18d7378b00b40847790e7c27e11673d7fed219354109d0e7b9e5b25dc3ad26", + "sha256:d5f18a79777f3aa179c145737780282e27b508fc8fd688cb17c7a813e8bd39af" + ], + "version": "==0.23" + }, + "jsonschema": { + "hashes": [ + "sha256:2fa0684276b6333ff3c0b1b27081f4b2305f0a36cf702a23db50edb141893c3f", + "sha256:94c0a13b4a0616458b42529091624e66700a17f847453e52279e35509a5b7631" + ], + "index": "pypi", + "version": "==3.1.1" + }, + "more-itertools": { + "hashes": [ + "sha256:409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832", + "sha256:92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4" + ], + "version": "==7.2.0" + }, + "pyrsistent": { + "hashes": [ + "sha256:34b47fa169d6006b32e99d4b3c4031f155e6e68ebcc107d6454852e8e0ee6533" + ], + "version": "==0.15.4" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + }, + "zipp": { + "hashes": [ + "sha256:3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e", + "sha256:f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335" + ], + "version": "==0.6.0" + } + }, + "develop": { + "apipkg": { + "hashes": [ + "sha256:37228cda29411948b422fae072f57e31d3396d2ee1c9783775980ee9c9990af6", + "sha256:58587dd4dc3daefad0487f6d9ae32b4542b185e1c36db6993290e7c41ca2b47c" + ], + "version": "==1.5" + }, + "argh": { + "hashes": [ + "sha256:a9b3aaa1904eeb78e32394cd46c6f37ac0fb4af6dc488daa58971bdc7d7fcaf3", + "sha256:e9535b8c84dc9571a48999094fda7f33e63c3f1b74f3e5f3ac0105a58405bb65" + ], + "version": "==0.26.2" + }, + "aspy.yaml": { + "hashes": [ + "sha256:463372c043f70160a9ec950c3f1e4c3a82db5fca01d334b6bc89c7164d744bdc", + "sha256:e7c742382eff2caed61f87a39d13f99109088e5e93f04d76eb8d4b28aa143f45" + ], + "version": "==1.3.0" + }, + "atomicwrites": { + "hashes": [ + "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", + "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6" + ], + "version": "==1.3.0" + }, + "attrs": { + "hashes": [ + "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", + "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" + ], + "version": "==19.3.0" + }, + "autopep8": { + "hashes": [ + "sha256:4d8eec30cc81bc5617dbf1218201d770dc35629363547f17577c61683ccfb3ee" + ], + "index": "pypi", + "version": "==1.4.4" + }, + "bleach": { + "hashes": [ + "sha256:213336e49e102af26d9cde77dd2d0397afabc5a6bf2fed985dc35b5d1e285a16", + "sha256:3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa" + ], + "version": "==3.1.0" + }, + "certifi": { + "hashes": [ + "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50", + "sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef" + ], + "version": "==2019.9.11" + }, + "cfgv": { + "hashes": [ + "sha256:edb387943b665bf9c434f717bf630fa78aecd53d5900d2e05da6ad6048553144", + "sha256:fbd93c9ab0a523bf7daec408f3be2ed99a980e20b2d19b50fc184ca6b820d289" + ], + "version": "==2.0.1" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, + "click": { + "hashes": [ + "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", + "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + ], + "version": "==7.0" + }, + "colorama": { + "hashes": [ + "sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", + "sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48" + ], + "version": "==0.4.1" + }, + "colorlog": { + "hashes": [ + "sha256:3cf31b25cbc8f86ec01fef582ef3b840950dea414084ed19ab922c8b493f9b42", + "sha256:450f52ea2a2b6ebb308f034ea9a9b15cea51e65650593dca1da3eb792e4e4981" + ], + "version": "==4.0.2" + }, + "coverage": { + "hashes": [ + "sha256:08907593569fe59baca0bf152c43f3863201efb6113ecb38ce7e97ce339805a6", + "sha256:0be0f1ed45fc0c185cfd4ecc19a1d6532d72f86a2bac9de7e24541febad72650", + "sha256:141f08ed3c4b1847015e2cd62ec06d35e67a3ac185c26f7635f4406b90afa9c5", + "sha256:19e4df788a0581238e9390c85a7a09af39c7b539b29f25c89209e6c3e371270d", + "sha256:23cc09ed395b03424d1ae30dcc292615c1372bfba7141eb85e11e50efaa6b351", + "sha256:245388cda02af78276b479f299bbf3783ef0a6a6273037d7c60dc73b8d8d7755", + "sha256:331cb5115673a20fb131dadd22f5bcaf7677ef758741312bee4937d71a14b2ef", + "sha256:386e2e4090f0bc5df274e720105c342263423e77ee8826002dcffe0c9533dbca", + "sha256:3a794ce50daee01c74a494919d5ebdc23d58873747fa0e288318728533a3e1ca", + "sha256:60851187677b24c6085248f0a0b9b98d49cba7ecc7ec60ba6b9d2e5574ac1ee9", + "sha256:63a9a5fc43b58735f65ed63d2cf43508f462dc49857da70b8980ad78d41d52fc", + "sha256:6b62544bb68106e3f00b21c8930e83e584fdca005d4fffd29bb39fb3ffa03cb5", + "sha256:6ba744056423ef8d450cf627289166da65903885272055fb4b5e113137cfa14f", + "sha256:7494b0b0274c5072bddbfd5b4a6c6f18fbbe1ab1d22a41e99cd2d00c8f96ecfe", + "sha256:826f32b9547c8091679ff292a82aca9c7b9650f9fda3e2ca6bf2ac905b7ce888", + "sha256:93715dffbcd0678057f947f496484e906bf9509f5c1c38fc9ba3922893cda5f5", + "sha256:9a334d6c83dfeadae576b4d633a71620d40d1c379129d587faa42ee3e2a85cce", + "sha256:af7ed8a8aa6957aac47b4268631fa1df984643f07ef00acd374e456364b373f5", + "sha256:bf0a7aed7f5521c7ca67febd57db473af4762b9622254291fbcbb8cd0ba5e33e", + "sha256:bf1ef9eb901113a9805287e090452c05547578eaab1b62e4ad456fcc049a9b7e", + "sha256:c0afd27bc0e307a1ffc04ca5ec010a290e49e3afbe841c5cafc5c5a80ecd81c9", + "sha256:dd579709a87092c6dbee09d1b7cfa81831040705ffa12a1b248935274aee0437", + "sha256:df6712284b2e44a065097846488f66840445eb987eb81b3cc6e4149e7b6982e1", + "sha256:e07d9f1a23e9e93ab5c62902833bf3e4b1f65502927379148b6622686223125c", + "sha256:e2ede7c1d45e65e209d6093b762e98e8318ddeff95317d07a27a2140b80cfd24", + "sha256:e4ef9c164eb55123c62411f5936b5c2e521b12356037b6e1c2617cef45523d47", + "sha256:eca2b7343524e7ba246cab8ff00cab47a2d6d54ada3b02772e908a45675722e2", + "sha256:eee64c616adeff7db37cc37da4180a3a5b6177f5c46b187894e633f088fb5b28", + "sha256:ef824cad1f980d27f26166f86856efe11eff9912c4fed97d3804820d43fa550c", + "sha256:efc89291bd5a08855829a3c522df16d856455297cf35ae827a37edac45f466a7", + "sha256:fa964bae817babece5aa2e8c1af841bebb6d0b9add8e637548809d040443fee0", + "sha256:ff37757e068ae606659c28c3bd0d923f9d29a85de79bf25b2b34b148473b5025" + ], + "index": "pypi", + "version": "==4.5.4" + }, + "docutils": { + "hashes": [ + "sha256:6c4f696463b79f1fb8ba0c594b63840ebd41f059e92b31957c46b74a4599b6d0", + "sha256:9e4d7ecfc600058e07ba661411a2b7de2fd0fafa17d1a7f7361cd47b1175c827", + "sha256:a2aeea129088da402665e92e0b25b04b073c04b2dce4ab65caaa38b7ce2e1a99" + ], + "version": "==0.15.2" + }, + "entrypoints": { + "hashes": [ + "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", + "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451" + ], + "version": "==0.3" + }, + "execnet": { + "hashes": [ + "sha256:cacb9df31c9680ec5f95553976c4da484d407e85e41c83cb812aa014f0eddc50", + "sha256:d4efd397930c46415f62f8a31388d6be4f27a91d7550eb79bc64a756e0056547" + ], + "version": "==1.7.1" + }, + "filelock": { + "hashes": [ + "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59", + "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836" + ], + "version": "==3.0.12" + }, + "flake8": { + "hashes": [ + "sha256:19241c1cbc971b9962473e4438a2ca19749a7dd002dd1a946eaba171b4114548", + "sha256:8e9dfa3cecb2400b3738a42c54c3043e821682b9c840b0448c0503f781130696" + ], + "index": "pypi", + "version": "==3.7.8" + }, + "flake8-bugbear": { + "hashes": [ + "sha256:d8c466ea79d5020cb20bf9f11cf349026e09517a42264f313d3f6fddb83e0571", + "sha256:ded4d282778969b5ab5530ceba7aa1a9f1b86fa7618fc96a19a1d512331640f8" + ], + "index": "pypi", + "version": "==19.8.0" + }, + "flake8-polyfill": { + "hashes": [ + "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9", + "sha256:e44b087597f6da52ec6393a709e7108b2905317d0c0b744cdca6208e670d8eda" + ], + "version": "==1.0.2" + }, + "future": { + "hashes": [ + "sha256:858e38522e8fd0d3ce8f0c1feaf0603358e366d5403209674c7b617fa0c24093" + ], + "version": "==0.18.1" + }, + "gitdb2": { + "hashes": [ + "sha256:1b6df1433567a51a4a9c1a5a0de977aa351a405cc56d7d35f3388bad1f630350", + "sha256:96bbb507d765a7f51eb802554a9cfe194a174582f772e0d89f4e87288c288b7b" + ], + "version": "==2.0.6" + }, + "gitpython": { + "hashes": [ + "sha256:17815b908454e49604e86ffb0e4d981c463d009b54ab30ead7f6ad8ad3a8cffb", + "sha256:392f31eaadc19db35a54e3ab7285577fb4a86d96ecee08cf22a573f06633baab" + ], + "version": "==2.1.14" + }, + "identify": { + "hashes": [ + "sha256:4f1fe9a59df4e80fcb0213086fcf502bc1765a01ea4fe8be48da3b65afd2a017", + "sha256:d8919589bd2a5f99c66302fec0ef9027b12ae150b0b0213999ad3f695fc7296e" + ], + "version": "==1.4.7" + }, + "idna": { + "hashes": [ + "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", + "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + ], + "version": "==2.8" + }, + "importlib-metadata": { + "hashes": [ + "sha256:aa18d7378b00b40847790e7c27e11673d7fed219354109d0e7b9e5b25dc3ad26", + "sha256:d5f18a79777f3aa179c145737780282e27b508fc8fd688cb17c7a813e8bd39af" + ], + "version": "==0.23" + }, + "isort": { + "hashes": [ + "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", + "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd" + ], + "index": "pypi", + "version": "==4.3.21" + }, + "jsonschema": { + "hashes": [ + "sha256:2fa0684276b6333ff3c0b1b27081f4b2305f0a36cf702a23db50edb141893c3f", + "sha256:94c0a13b4a0616458b42529091624e66700a17f847453e52279e35509a5b7631" + ], + "index": "pypi", + "version": "==3.1.1" + }, + "mando": { + "hashes": [ + "sha256:4ce09faec7e5192ffc3c57830e26acba0fd6cd11e1ee81af0d4df0657463bd1c", + "sha256:79feb19dc0f097daa64a1243db578e7674909b75f88ac2220f1c065c10a0d960" + ], + "version": "==0.6.4" + }, + "mccabe": { + "hashes": [ + "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", + "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + ], + "version": "==0.6.1" + }, + "more-itertools": { + "hashes": [ + "sha256:409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832", + "sha256:92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4" + ], + "version": "==7.2.0" + }, + "mypy": { + "hashes": [ + "sha256:1521c186a3d200c399bd5573c828ea2db1362af7209b2adb1bb8532cea2fb36f", + "sha256:31a046ab040a84a0fc38bc93694876398e62bc9f35eca8ccbf6418b7297f4c00", + "sha256:3b1a411909c84b2ae9b8283b58b48541654b918e8513c20a400bb946aa9111ae", + "sha256:48c8bc99380575deb39f5d3400ebb6a8a1cb5cc669bbba4d3bb30f904e0a0e7d", + "sha256:540c9caa57a22d0d5d3c69047cc9dd0094d49782603eb03069821b41f9e970e9", + "sha256:672e418425d957e276c291930a3921b4a6413204f53fe7c37cad7bc57b9a3391", + "sha256:6ed3b9b3fdc7193ea7aca6f3c20549b377a56f28769783a8f27191903a54170f", + "sha256:9371290aa2cad5ad133e4cdc43892778efd13293406f7340b9ffe99d5ec7c1d9", + "sha256:ace6ac1d0f87d4072f05b5468a084a45b4eda970e4d26704f201e06d47ab2990", + "sha256:b428f883d2b3fe1d052c630642cc6afddd07d5cd7873da948644508be3b9d4a7", + "sha256:d5bf0e6ec8ba346a2cf35cb55bf4adfddbc6b6576fcc9e10863daa523e418dbb", + "sha256:d7574e283f83c08501607586b3167728c58e8442947e027d2d4c7dcd6d82f453", + "sha256:dc889c84241a857c263a2b1cd1121507db7d5b5f5e87e77147097230f374d10b", + "sha256:f4748697b349f373002656bf32fede706a0e713d67bfdcf04edf39b1f61d46eb" + ], + "index": "pypi", + "version": "==0.740" + }, + "mypy-extensions": { + "hashes": [ + "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", + "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" + ], + "version": "==0.4.3" + }, + "nodeenv": { + "hashes": [ + "sha256:ad8259494cf1c9034539f6cced78a1da4840a4b157e23640bc4a0c0546b0cb7a" + ], + "version": "==1.3.3" + }, + "packaging": { + "hashes": [ + "sha256:28b924174df7a2fa32c1953825ff29c61e2f5e082343165438812f00d3a7fc47", + "sha256:d9551545c6d761f3def1677baf08ab2a3ca17c56879e70fecba2fc4dde4ed108" + ], + "version": "==19.2" + }, + "pathtools": { + "hashes": [ + "sha256:7c35c5421a39bb82e58018febd90e3b6e5db34c5443aaaf742b3f33d4655f1c0" + ], + "version": "==0.1.2" + }, + "pkginfo": { + "hashes": [ + "sha256:7424f2c8511c186cd5424bbf31045b77435b37a8d604990b79d4e70d741148bb", + "sha256:a6d9e40ca61ad3ebd0b72fbadd4fba16e4c0e4df0428c041e01e06eb6ee71f32" + ], + "version": "==1.5.0.1" + }, + "plotly": { + "hashes": [ + "sha256:593418bbbd325ee020b7d0381a9452c603558981bde05a303b860455eb907574", + "sha256:6650ddb4da3aa94dcaa32e0779e611c6b17f371b5250ffdbf5ece6d66ba4483b" + ], + "version": "==4.2.1" + }, + "pluggy": { + "hashes": [ + "sha256:0db4b7601aae1d35b4a033282da476845aa19185c1e6964b25cf324b5e4ec3e6", + "sha256:fa5fa1622fa6dd5c030e9cad086fa19ef6a0cf6d7a2d12318e10cb49d6d68f34" + ], + "version": "==0.13.0" + }, + "pre-commit": { + "hashes": [ + "sha256:1d3c0587bda7c4e537a46c27f2c84aa006acc18facf9970bf947df596ce91f3f", + "sha256:fa78ff96e8e9ac94c748388597693f18b041a181c94a4f039ad20f45287ba44a" + ], + "index": "pypi", + "version": "==1.18.3" + }, + "progress": { + "hashes": [ + "sha256:5e2f9da88ed8236a76fffbee3ceefd259589cf42dfbc2cec2877102189fae58a" + ], + "version": "==1.4" + }, + "py": { + "hashes": [ + "sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", + "sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53" + ], + "version": "==1.8.0" + }, + "pyclean-py": { + "hashes": [ + "sha256:9fe408486edc5d5f667390c025222339ca3e624f6cc7e7cdf550b6052704afab" + ], + "index": "pypi", + "version": "==0.0.1" + }, + "pycodestyle": { + "hashes": [ + "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", + "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c" + ], + "version": "==2.5.0" + }, + "pydocstyle": { + "hashes": [ + "sha256:04c84e034ebb56eb6396c820442b8c4499ac5eb94a3bda88951ac3dc519b6058", + "sha256:66aff87ffe34b1e49bff2dd03a88ce6843be2f3346b0c9814410d34987fbab59" + ], + "index": "pypi", + "version": "==4.0.1" + }, + "pyflakes": { + "hashes": [ + "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0", + "sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2" + ], + "version": "==2.1.1" + }, + "pygments": { + "hashes": [ + "sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127", + "sha256:881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297" + ], + "version": "==2.4.2" + }, + "pyparsing": { + "hashes": [ + "sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80", + "sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4" + ], + "version": "==2.4.2" + }, + "pyrsistent": { + "hashes": [ + "sha256:34b47fa169d6006b32e99d4b3c4031f155e6e68ebcc107d6454852e8e0ee6533" + ], + "version": "==0.15.4" + }, + "pytest": { + "hashes": [ + "sha256:7e4800063ccfc306a53c461442526c5571e1462f61583506ce97e4da6a1d88c8", + "sha256:ca563435f4941d0cb34767301c27bc65c510cb82e90b9ecf9cb52dc2c63caaa0" + ], + "index": "pypi", + "version": "==5.2.1" + }, + "pytest-cov": { + "hashes": [ + "sha256:cc6742d8bac45070217169f5f72ceee1e0e55b0221f54bcf24845972d3a47f2b", + "sha256:cdbdef4f870408ebdbfeb44e63e07eb18bb4619fae852f6e760645fa36172626" + ], + "index": "pypi", + "version": "==2.8.1" + }, + "pytest-forked": { + "hashes": [ + "sha256:e2d46f319c8063a3a0536b18f9cdea6eea3bc9fe2cb16c94e1d6fad3abc37300" + ], + "version": "==1.1.1" + }, + "pytest-mock": { + "hashes": [ + "sha256:34520283d459cdf1d0dbb58a132df804697f1b966ecedf808bbf3d255af8f659", + "sha256:f1ab8aefe795204efe7a015900296d1719e7bf0f4a0558d71e8599da1d1309d0" + ], + "index": "pypi", + "version": "==1.11.1" + }, + "pytest-only": { + "hashes": [ + "sha256:221d9c8094dde089d1c2dac6972ae2b47d95a8e13d5282e0289f8b27f06e3637" + ], + "index": "pypi", + "version": "==1.2.1" + }, + "pytest-xdist": { + "hashes": [ + "sha256:5d1b1d4461518a6023d56dab62fb63670d6f7537f23e2708459a557329accf48", + "sha256:a8569b027db70112b290911ce2ed732121876632fb3f40b1d39cd2f72f58b147" + ], + "index": "pypi", + "version": "==1.30.0" + }, + "pyyaml": { + "hashes": [ + "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9", + "sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4", + "sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8", + "sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696", + "sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34", + "sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9", + "sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73", + "sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299", + "sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b", + "sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae", + "sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681", + "sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41", + "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8" + ], + "version": "==5.1.2" + }, + "radon": { + "hashes": [ + "sha256:0cde1953547a164d24420ed6ccdfa18b61f1457b96a2b99ff0de76b22d504a0f", + "sha256:ee20308ce8bae7a89b067425b63b141a0077632ab318d5288da649c830882b3d" + ], + "version": "==3.0.3" + }, + "readme-renderer": { + "hashes": [ + "sha256:bb16f55b259f27f75f640acf5e00cf897845a8b3e4731b5c1a436e4b8529202f", + "sha256:c8532b79afc0375a85f10433eca157d6b50f7d6990f337fa498c96cd4bfc203d" + ], + "version": "==24.0" + }, + "requests": { + "hashes": [ + "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", + "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" + ], + "version": "==2.22.0" + }, + "requests-toolbelt": { + "hashes": [ + "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f", + "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0" + ], + "version": "==0.9.1" + }, + "retrying": { + "hashes": [ + "sha256:08c039560a6da2fe4f2c426d0766e284d3b736e355f8dd24b37367b0bb41973b" + ], + "version": "==1.3.3" + }, + "rope": { + "hashes": [ + "sha256:6b728fdc3e98a83446c27a91fc5d56808a004f8beab7a31ab1d7224cecc7d969", + "sha256:c5c5a6a87f7b1a2095fb311135e2a3d1f194f5ecb96900fdd0a9100881f48aaf", + "sha256:f0dcf719b63200d492b85535ebe5ea9b29e0d0b8aebeb87fe03fc1a65924fdaf" + ], + "index": "pypi", + "version": "==0.14.0" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + }, + "smmap2": { + "hashes": [ + "sha256:0555a7bf4df71d1ef4218e4807bbf9b201f910174e6e08af2e138d4e517b4dde", + "sha256:29a9ffa0497e7f2be94ca0ed1ca1aa3cd4cf25a1f6b4f5f87f74b46ed91d609a" + ], + "version": "==2.0.5" + }, + "snowballstemmer": { + "hashes": [ + "sha256:209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0", + "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52" + ], + "version": "==2.0.0" + }, + "tabulate": { + "hashes": [ + "sha256:d0097023658d4dea848d6ae73af84532d1e86617ac0925d1adf1dd903985dac3" + ], + "version": "==0.8.5" + }, + "toml": { + "hashes": [ + "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", + "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e" + ], + "version": "==0.10.0" + }, + "tox": { + "hashes": [ + "sha256:0bc216b6a2e6afe764476b4a07edf2c1dab99ed82bb146a1130b2e828f5bff5e", + "sha256:c4f6b319c20ba4913dbfe71ebfd14ff95d1853c4231493608182f66e566ecfe1" + ], + "index": "pypi", + "version": "==3.14.0" + }, + "tox-pipenv-install": { + "hashes": [ + "sha256:6bea3c88622d2cfc94ef2a5a36b656d0c9ea82ad7a82213c0097f571b77d0863", + "sha256:b406939613526895e633acdb590fcd39c0cd1def722cec44f78d5c8d73f13197" + ], + "index": "pypi", + "version": "==0.1.1" + }, + "tqdm": { + "hashes": [ + "sha256:abc25d0ce2397d070ef07d8c7e706aede7920da163c64997585d42d3537ece3d", + "sha256:dd3fcca8488bb1d416aa7469d2f277902f26260c45aa86b667b074cd44b3b115" + ], + "version": "==4.36.1" + }, + "twine": { + "hashes": [ + "sha256:5319dd3e02ac73fcddcd94f035b9631589ab5d23e1f4699d57365199d85261e1", + "sha256:9fe7091715c7576df166df8ef6654e61bada39571783f2fd415bdcba867c6993" + ], + "index": "pypi", + "version": "==2.0.0" + }, + "typed-ast": { + "hashes": [ + "sha256:1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", + "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", + "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", + "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", + "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", + "sha256:48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", + "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", + "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", + "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", + "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", + "sha256:7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", + "sha256:838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", + "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", + "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", + "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", + "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", + "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", + "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", + "sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", + "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12" + ], + "version": "==1.4.0" + }, + "typing-extensions": { + "hashes": [ + "sha256:2ed632b30bb54fc3941c382decfd0ee4148f5c591651c9272473fea2c6397d95", + "sha256:b1edbbf0652660e32ae780ac9433f4231e7339c7f9a8057d0f042fcbcea49b87", + "sha256:d8179012ec2c620d3791ca6fe2bf7979d979acdbef1fca0bc56b37411db682ed" + ], + "version": "==3.7.4" + }, + "urllib3": { + "hashes": [ + "sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398", + "sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86" + ], + "version": "==1.25.6" + }, + "virtualenv": { + "hashes": [ + "sha256:3e3597e89c73df9313f5566e8fc582bd7037938d15b05329c232ec57a11a7ad5", + "sha256:5d370508bf32e522d79096e8cbea3499d47e624ac7e11e9089f9397a0b3318df" + ], + "version": "==16.7.6" + }, + "watchdog": { + "hashes": [ + "sha256:965f658d0732de3188211932aeb0bb457587f04f63ab4c1e33eab878e9de961d" + ], + "index": "pypi", + "version": "==0.9.0" + }, + "wcwidth": { + "hashes": [ + "sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e", + "sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c" + ], + "version": "==0.1.7" + }, + "webencodings": { + "hashes": [ + "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", + "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" + ], + "version": "==0.5.1" + }, + "wily": { + "hashes": [ + "sha256:4911887351d37f08b67d20611f5dd05f27d85ec43385295f7e530585a68086a0", + "sha256:7d0b0f6b13c4b93e65e377c839d2a74a4618274f2dbf2ababaaf19799a7febf9" + ], + "index": "pypi", + "version": "==1.12.4" + }, + "zipp": { + "hashes": [ + "sha256:3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e", + "sha256:f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335" + ], + "version": "==0.6.0" + } + } +} diff --git a/README.md b/README.md index 65b19f4..64be218 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,34 @@ # pycon-schemas -Collection of data schemas and scripts for PyCons. +[![Build Status](https://travis-ci.org/PythonSanSebastian/pycon-schemas.svg?branch=master)](https://travis-ci.org/PythonSanSebastian/pycon-schemas) + + +## How to collaborate + +This project uses [pipenv](https://pipenv.readthedocs.io) to manage its dependencies +and Python environment. You can install it by: + +```bash +pip install --user pipenv +``` + +We recommend using a Python virtual environment for each separate project you do. +For that, we suggest using [pyenv](https://github.com/pyenv/pyenv-installer). + +### Installation + +For development you should also install the development dependencies, +so run instead: + +```bash +cd +make install-dev +``` + +This will install all dependencies and this project in development mode. + +### Testing + +We use [tox](https://tox.readthedocs.io/en/latest/) to run the code checkers. + +You can run the tests by running `tox` in the top-level of the project. diff --git a/pycon_schemas/__init__.py b/pycon_schemas/__init__.py new file mode 100644 index 0000000..c14c045 --- /dev/null +++ b/pycon_schemas/__init__.py @@ -0,0 +1,9 @@ +from .reader import get_schema + +participant_schema = get_schema('participant') +speaker_schema = get_schema('speaker') +sponsor_contact_schema = get_schema('sponsor_contact') +sponsor_schema = get_schema('sponsor') +sponsorships_schema = get_schema('sponsorships') +submission_schema = get_schema('submission') +talk_schema = get_schema('talk') diff --git a/pycon_schemas/conftest.py b/pycon_schemas/conftest.py new file mode 100644 index 0000000..fa79dd8 --- /dev/null +++ b/pycon_schemas/conftest.py @@ -0,0 +1,47 @@ +import os +import json + +import pytest +from jsonschema import RefResolver, Draft7Validator + +import pycon_schemas + + +@pytest.fixture +def examples_path(): + cwd = os.path.dirname(__file__) + return os.path.join(cwd, 'tests', 'examples') + + +@pytest.fixture +def schemas_path(): + module_path = os.path.dirname(pycon_schemas.__file__) + return os.path.join(module_path, 'schemas') + + +@pytest.fixture +def load_example(examples_path): + def example_loader(example_file): + with open(os.path.join(examples_path, example_file)) as f: + return json.load(f) + return example_loader + + +@pytest.fixture +def check_schema(): + return Draft7Validator.check_schema + + +@pytest.fixture +def validator(schemas_path): + class JsonSchemaValidator: + + def __init__(self, resolver): + self.resolver = resolver + + def validate(self, instance, schema): + validator = Draft7Validator(schema=schema, resolver=self.resolver) + return validator.validate(instance) + + resolver = RefResolver('file://' + schemas_path, None) + return JsonSchemaValidator(resolver) diff --git a/pycon_schemas/reader.py b/pycon_schemas/reader.py new file mode 100644 index 0000000..eef2d49 --- /dev/null +++ b/pycon_schemas/reader.py @@ -0,0 +1,14 @@ +import os +import json + + +def schemas_path(): + module_path = os.path.dirname(__file__) + return os.path.join(module_path, 'schemas') + + +def get_schema(schema_name): + schema_path = os.path.join(schemas_path(), f'{schema_name}.json') + with open(schema_path) as f: + schema = f.read() + return json.loads(schema) diff --git a/pycon_schemas/schemas/participant.json b/pycon_schemas/schemas/participant.json new file mode 100644 index 0000000..7e61b18 --- /dev/null +++ b/pycon_schemas/schemas/participant.json @@ -0,0 +1,110 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://pycon.org/participant.json", + "title": "Participant", + "description": "A schema for an organizers view of a conference participant", + "type": "object", + "required": [ + ], + "properties": { + "code": { + "$id": "#/properties/code", + "type": "string", + "title": "The Code Schema", + "default": "", + "examples": [ + "UZVQTV" + ], + "pattern": "^(.*)$" + }, + "name": { + "$id": "#/properties/name", + "type": "string", + "title": "The Name Schema", + "default": "", + "examples": [ + "Jean Doe" + ], + "pattern": "^(.*)$" + }, + "email": { + "$id": "#/properties/email", + "type": "string", + "title": "The Email Schema", + "default": "", + "examples": [ + "someone@pycon.com" + ], + "pattern": "^(.*)$" + }, + "biography": { + "$id": "#/properties/biography", + "type": "string", + "title": "The Biography Schema", + "default": "", + "examples": [ + "Jean is a great person" + ], + "pattern": "^(.*)$" + }, + "homepage": { + "$id": "#/properties/homepage", + "type": "null", + "title": "The Homepage Schema", + "default": null, + "examples": [ + null + ] + }, + "profile_picture": { + "$id": "#/properties/profile_picture", + "type": "null", + "title": "The Profile_picture Schema", + "default": null, + "examples": [ + null + ] + }, + "job_position": { + "$id": "#/properties/job_position", + "type": "null", + "title": "The Job_position Schema", + "default": null, + "examples": [ + null + ] + }, + "affiliation": { + "$id": "#/properties/affiliation", + "type": "null", + "title": "The Affiliation Schema", + "default": null, + "examples": [ + null + ] + }, + "twitter": { + "$id": "#/properties/twitter", + "type": "null", + "title": "The Twitter Schema", + "default": null, + "examples": [ + null + ] + }, + "gender": { + "$id": "#/properties/gender", + "type": "null", + "title": "The Gender Schema", + "default": null, + "examples": [ + null + ] + }, + "languages": { + "$id": "#/properties/languages", + "type": "array", + "title": "The Languages Schema" + } + } +} diff --git a/pycon_schemas/schemas/speaker.json b/pycon_schemas/schemas/speaker.json new file mode 100644 index 0000000..08efe9c --- /dev/null +++ b/pycon_schemas/schemas/speaker.json @@ -0,0 +1,108 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://pycon.org/speaker.json", + "title": "Speaker", + "description": "A schema for a public view of a speaker", + "type": "object", + "properties": { + "code": { + "$id": "#/properties/code", + "type": "string", + "title": "The Code Schema", + "default": "", + "examples": [ + "UZVQTV" + ], + "pattern": "^(.*)$" + }, + "name": { + "$id": "#/properties/name", + "type": "string", + "title": "The Name Schema", + "default": "", + "examples": [ + "Jean Doe" + ], + "pattern": "^(.*)$" + }, + "email": { + "$id": "#/properties/email", + "type": "string", + "title": "The Email Schema", + "default": "", + "examples": [ + "someone@pycon.com" + ], + "pattern": "^(.*)$" + }, + "biography": { + "$id": "#/properties/biography", + "type": "string", + "title": "The Biography Schema", + "default": "", + "examples": [ + "Jean is a great person" + ], + "pattern": "^(.*)$" + }, + "homepage": { + "$id": "#/properties/homepage", + "type": "null", + "title": "The Homepage Schema", + "default": null, + "examples": [ + null + ] + }, + "profile_picture": { + "$id": "#/properties/profile_picture", + "type": "null", + "title": "The Profile_picture Schema", + "default": null, + "examples": [ + null + ] + }, + "job_position": { + "$id": "#/properties/job_position", + "type": "null", + "title": "The Job_position Schema", + "default": null, + "examples": [ + null + ] + }, + "affiliation": { + "$id": "#/properties/affiliation", + "type": "null", + "title": "The Affiliation Schema", + "default": null, + "examples": [ + null + ] + }, + "twitter": { + "$id": "#/properties/twitter", + "type": "null", + "title": "The Twitter Schema", + "default": null, + "examples": [ + null + ] + }, + "gender": { + "$id": "#/properties/gender", + "type": "null", + "title": "The Gender Schema", + "default": null, + "examples": [ + null + ] + }, + "languages": { + "$id": "#/properties/languages", + "type": "array", + "title": "The Languages Schema" + } + } +} diff --git a/pycon_schemas/schemas/sponsor.json b/pycon_schemas/schemas/sponsor.json new file mode 100644 index 0000000..449c827 --- /dev/null +++ b/pycon_schemas/schemas/sponsor.json @@ -0,0 +1,49 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://pycon.org/sponsor.json", + "title": "Sponsor", + "description": "A schema for a public view of a sponsor", + "type": "object", + "required": [ + "name", + "logo" + ], + "properties": { + "name": { + "description": "Full name of the company", + "type": "string", + "examples": [ + "Python Conference" + ] + }, + "shortName": { + "description": "Short name of the company", + "type": "string", + "examples": [ + "PyCon" + ] + }, + "description": { + "description": "A description of the company", + "type": "string", + "examples": [ + "Super cool company" + ] + }, + "url": { + "description": "The sponsors website", + "type": "string", + "examples": [ + "https://www.pycon.org" + ] + }, + "logo": { + "description": "Local path or URL to the logo file", + "type": "string", + "examples": [ + "static/pycon_logo.png", + "https://www.pycon.org/static/logo.png" + ] + } + } +} diff --git a/pycon_schemas/schemas/sponsor_contact.json b/pycon_schemas/schemas/sponsor_contact.json new file mode 100644 index 0000000..86e364e --- /dev/null +++ b/pycon_schemas/schemas/sponsor_contact.json @@ -0,0 +1,10 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://pycon.org/sponsor_contact.json", + "title": "SponsorContact", + "description": "A schema for an organizers' view of a sponsor", + "type": "object", + "properties": { + + } +} diff --git a/pycon_schemas/schemas/sponsorships.json b/pycon_schemas/schemas/sponsorships.json new file mode 100644 index 0000000..2dfb3a8 --- /dev/null +++ b/pycon_schemas/schemas/sponsorships.json @@ -0,0 +1,34 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://pycon.org/sponsorships.json", + "title": "Sponsorships", + "description": "A schema for a public view of sponsor companies", + "type": "array", + "items": { + "description": "The list of sponsors aggregated by sponsorship type", + "items": { + "$ref": "#/$def/sponsorship" + } + }, + "$def": { + "sponsorship": { + "type": "object", + "required": ["type", "sponsors"], + "properties": { + "type": { + "description": "The type of the sponsorship of the companies in this group", + "type": "string", + "examples": [ + "Gold sponsors" + ] + }, + "sponsors": { + "type": "array", + "items": { + "$ref": "sponsor.json" + } + } + } + } + } +} diff --git a/pycon_schemas/schemas/submission.json b/pycon_schemas/schemas/submission.json new file mode 100644 index 0000000..f44cd5d --- /dev/null +++ b/pycon_schemas/schemas/submission.json @@ -0,0 +1,19 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://pycon.org/submission.json", + "title": "Submission", + "description": "A schema for a organizers view of a talk/training/poster submission", + "type": "object", + "required": [ + "title" + ], + "properties": { + "title": { + "description": "Title of the submission", + "type": "string", + "examples": [ + "Introduction to jsonschema" + ] + } + } +} diff --git a/pycon_schemas/schemas/talk.json b/pycon_schemas/schemas/talk.json new file mode 100644 index 0000000..c4b7447 --- /dev/null +++ b/pycon_schemas/schemas/talk.json @@ -0,0 +1,19 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://pycon.org/talk.json", + "title": "Talk", + "description": "A schema for a public view of a talk", + "type": "object", + "required": [ + "title" + ], + "properties": { + "title": { + "description": "Title of the talk", + "type": "string", + "examples": [ + "Introduction to jsonschema" + ] + } + } +} diff --git a/pycon_schemas/tests/examples/participant.json b/pycon_schemas/tests/examples/participant.json new file mode 100644 index 0000000..e69de29 diff --git a/schemas/speaker.json b/pycon_schemas/tests/examples/speaker.json similarity index 100% rename from schemas/speaker.json rename to pycon_schemas/tests/examples/speaker.json diff --git a/pycon_schemas/tests/examples/sponsor.json b/pycon_schemas/tests/examples/sponsor.json new file mode 100644 index 0000000..b541278 --- /dev/null +++ b/pycon_schemas/tests/examples/sponsor.json @@ -0,0 +1,6 @@ +{ + "name": "Microsoft", + "shortName": "Microsoft", + "description": "Microsoft is proud to support the Python Community and the PyCon DE & PyData Berlin Conference. Visual Studio Code, our lightweight, free and open source editor lets developers write better code faster with extensions for Python. Microsoft Azure enables you to develop & run your code easily in the cloud. Azure DevOps supports you to automate the deployment of your data application.", + "logo": "/static/media/sponsors/microsoft.png" +} diff --git a/pycon_schemas/tests/examples/sponsor_contact.json b/pycon_schemas/tests/examples/sponsor_contact.json new file mode 100644 index 0000000..e69de29 diff --git a/pycon_schemas/tests/examples/sponsorships.json b/pycon_schemas/tests/examples/sponsorships.json new file mode 100644 index 0000000..bf164e9 --- /dev/null +++ b/pycon_schemas/tests/examples/sponsorships.json @@ -0,0 +1,18 @@ +[ + { + "level": "Diamond sponsors", + "sponsors": [ + { + "name": "Anaconda", + "shortName": "Anaconda", + "description": "With more than 15 million users, Anaconda is the world’s most popular data science platform and the foundation of modern machine learning. Our flagship product, Anaconda Enterprise, delivers data science and machine learning at speed and scale, unleashing the full potential of our customers’ data science and machine learning initiatives.", + "logo": "/static/media/sponsors/anaconda.jpg" + }, + { + "name": "Microsoft", + "description": "Microsoft is proud to support the Python Community and the PyCon DE & PyData Berlin Conference. Visual Studio Code, our lightweight, free and open source editor lets developers write better code faster with extensions for Python. Microsoft Azure enables you to develop & run your code easily in the cloud. Azure DevOps supports you to automate the deployment of your data application.", + "logo": "/static/media/sponsors/microsoft.png" + } + ] + } +] diff --git a/pycon_schemas/tests/examples/submission.json b/pycon_schemas/tests/examples/submission.json new file mode 100644 index 0000000..e69de29 diff --git a/schemas/talk.json b/pycon_schemas/tests/examples/talk.json similarity index 82% rename from schemas/talk.json rename to pycon_schemas/tests/examples/talk.json index cf9dfc8..def035c 100644 --- a/schemas/talk.json +++ b/pycon_schemas/tests/examples/talk.json @@ -19,13 +19,6 @@ "do_not_record": false, "is_featured": true, "content_locale": "en", - "slot": { - "room": { - "en": "Track 1 (Mitxelena)" - }, - "start": "2019-09-05T10:30:00Z", - "end": "2019-09-05T11:00:00Z" - }, "image": null, "project_homepage": null, "resources": [], diff --git a/pycon_schemas/tests/test_participant.py b/pycon_schemas/tests/test_participant.py new file mode 100644 index 0000000..c86c0c3 --- /dev/null +++ b/pycon_schemas/tests/test_participant.py @@ -0,0 +1,17 @@ +import pytest + +from pycon_schemas import participant_schema + + +@pytest.fixture +def participant_example(load_example): + return load_example('participant.json') + + +class TestParticipantSchema: + + def test_participant_schema_check(self, check_schema): + check_schema(participant_schema) + + def test_participant_example_valid(self, validator, participant_example): + validator.validate(instance=participant_example, schema=participant_schema) diff --git a/pycon_schemas/tests/test_speaker.py b/pycon_schemas/tests/test_speaker.py new file mode 100644 index 0000000..d849806 --- /dev/null +++ b/pycon_schemas/tests/test_speaker.py @@ -0,0 +1,17 @@ +import pytest + +from pycon_schemas import speaker_schema + + +@pytest.fixture +def speaker_example(load_example): + return load_example('speaker.json') + + +class TestSpeakerSchema: + + def test_speaker_schema_check(self, check_schema): + check_schema(speaker_schema) + + def test_speaker_example_valid(self, validator, speaker_example): + validator.validate(instance=speaker_example, schema=speaker_schema) diff --git a/pycon_schemas/tests/test_sponsor.py b/pycon_schemas/tests/test_sponsor.py new file mode 100644 index 0000000..e9befd5 --- /dev/null +++ b/pycon_schemas/tests/test_sponsor.py @@ -0,0 +1,17 @@ +import pytest + +from pycon_schemas import sponsor_schema + + +@pytest.fixture +def sponsor_example(load_example): + return load_example('sponsor.json') + + +class TestSponsorSchema: + + def test_sponsor_schema_check(self, check_schema): + check_schema(sponsor_schema) + + def test_sponsor_example_valid(self, validator, sponsor_example): + validator.validate(instance=sponsor_example, schema=sponsor_schema) diff --git a/pycon_schemas/tests/test_sponsor_contact.py b/pycon_schemas/tests/test_sponsor_contact.py new file mode 100644 index 0000000..5aed235 --- /dev/null +++ b/pycon_schemas/tests/test_sponsor_contact.py @@ -0,0 +1,17 @@ +import pytest + +from pycon_schemas import sponsor_contact_schema + + +@pytest.fixture +def sponsor_contact_example(load_example): + return load_example('sponsor_contact.json') + + +class TestSponsorContactSchema: + + def test_sponsor_contact_schema_check(self, check_schema): + check_schema(sponsor_contact_schema) + + def test_sponsor_contact_example_valid(self, validator, sponsor_contact_example): + validator.validate(instance=sponsor_contact_example, schema=sponsor_contact_schema) diff --git a/pycon_schemas/tests/test_sponsorships.py b/pycon_schemas/tests/test_sponsorships.py new file mode 100644 index 0000000..5fdf16a --- /dev/null +++ b/pycon_schemas/tests/test_sponsorships.py @@ -0,0 +1,17 @@ +import pytest + +from pycon_schemas import sponsorships_schema + + +@pytest.fixture +def sponsorships_example(load_example): + return load_example('sponsorships.json') + + +class TestSponsorListSchema: + + def test_sponsorships_schema_check(self, check_schema): + check_schema(sponsorships_schema) + + def test_sponsorships_example_valid(self, validator, sponsorships_example): + validator.validate(instance=sponsorships_example, schema=sponsorships_schema) diff --git a/pycon_schemas/tests/test_submission.py b/pycon_schemas/tests/test_submission.py new file mode 100644 index 0000000..30eade9 --- /dev/null +++ b/pycon_schemas/tests/test_submission.py @@ -0,0 +1,17 @@ +import pytest + +from pycon_schemas import submission_schema + + +@pytest.fixture +def submission_example(load_example): + return load_example('submission.json') + + +class TestSubmissionSchema: + + def test_submission_schema_check(self, check_schema): + check_schema(submission_schema) + + def test_submission_example_valid(self, validator, submission_example): + validator.validate(instance=submission_example, schema=submission_schema) diff --git a/pycon_schemas/tests/test_talk.py b/pycon_schemas/tests/test_talk.py new file mode 100644 index 0000000..859bb2f --- /dev/null +++ b/pycon_schemas/tests/test_talk.py @@ -0,0 +1,17 @@ +import pytest + +from pycon_schemas import talk_schema + + +@pytest.fixture +def talk_example(load_example): + return load_example('talk.json') + + +class TestTalkSchema: + + def test_talk_schema_check(self, check_schema): + check_schema(talk_schema) + + def test_talk_example_valid(self, validator, talk_example): + validator.validate(instance=talk_example, schema=talk_schema) diff --git a/pycon_schemas/validator.py b/pycon_schemas/validator.py new file mode 100644 index 0000000..c0cf150 --- /dev/null +++ b/pycon_schemas/validator.py @@ -0,0 +1,11 @@ +from jsonschema import RefResolver, Draft7Validator + +from .reader import schemas_path + +pycon_schema_resolver = RefResolver('file://' + schemas_path(), None) + + +class PyconSchemaValidator(Draft7Validator): + + def __init__(self, *args, **kwargs): + super().__init__(*args, resolver=pycon_schema_resolver, **kwargs) diff --git a/pycon_schemas/version.py b/pycon_schemas/version.py new file mode 100644 index 0000000..9ad5827 --- /dev/null +++ b/pycon_schemas/version.py @@ -0,0 +1,2 @@ +"""Release version number.""" +__version__ = '0.0.1' # noqa diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..f45aeb7 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,124 @@ +[metadata] +name = pycon-schemas +version = attr: pycon_schemas.version.__version__ +description = A collection of jsonschema entityes for PyCons +long_description = file: README.md +long_description_content_type = text/markdown +project_urls = + Source Code = https://github.com/PythonSanSebastian/pycon-schemas + Bug Tracker = https://github.com/PythonSanSebastian/pycon-schemas/issues + Changelog = https://github.com/PythonSanSebastian/pycon-schemas/blob/master/CHANGELOG.md +author = Alexandre Savio +author_email = alexsavio@gmail.com +license = MIT License +license-file = LICENSE +keywords = + pycon + jsonschema +classifiers = + Development Status :: 5 - Production/Stable + Environment :: Other Environment + Intended Audience :: Developers + License :: OSI Approved :: MIT License + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.7 + +[options] +python_requires = >=3.7 +packages = find: +include_package_data = True +test_suite = tests +setup_requires = + wheel + setuptools + pytest-runner +install_requires = +tests_require = + pytest + jsonschema==3.1.1 + +[pydocstyle] +inherit = false +match = (?!test_).*\.py +ignore-decorators = property + +[flake8] +max-line-length = 120 +max-complexity = 10 +select = C,E,F,W,B,B950 +ignore = E501,E126 + +[isort] +multi_line_output = 3 +include_trailing_comma = True +use_parentheses = True +force_single_line = False +indent = 4 +line_length = 120 +wrap_length = 60 +not_skip = __init__.py +length_sort = True +known_first_party = pycon_schemas +known_third_party = pytest,jsonschema +sections = FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER + +[mypy] +python_version = 3.7 +ignore_missing_imports = True +warn_unused_configs = True + +[tox:tox] +envlist = + lint, + # doclint, + isort, + mypy, + tests +skipsdist = True + +[tool:pytest] +filterwarnings = + ignore::DeprecationWarning + +[coverage:run] +branch = True + +[coverage:report] +include = + pycon_schemas/* +omit = + */tests/* + +[testenv] +basepython = python3 +whitelist_externals = make +deps = + lint: flake8 + lint: flake8-bugbear + isort: isort + mypy: mypy + doclint: pydocstyle +passenv = + CI = 1 +setenv = + PYTHONPATH = {toxinidir}:{toxinidir} + TESTING = True +commands = + lint: flake8 pycon_schemas + isort: isort -c -rc pycon_schemas + mypy: mypy pycon_schemas + doclint: pydocstyle -v pycon_schemas + +[testenv:tests] +deps = + coverage +commands = + python setup.py develop + coverage run -m pytest + coverage report + +[testenv:docs] +deps = -rdocs/requirements.txt +changedir = {toxinidir}/docs +commands = + sphinx-build -b html -d {envtmpdir}/doctrees . {envtmpdir}/html diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..85a38ac --- /dev/null +++ b/setup.py @@ -0,0 +1,5 @@ +"""Define the setup function using setup.cfg.""" + +from setuptools import setup + +setup()