diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..6be1e24 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,38 @@ +# Git +.git +.gitignore +.github + +# Docker +.dockerignore + +# IDE +.idea +.vscode + +# Byte-compiled / optimized / DLL files +__pycache__/ +**/__pycache__/ +*.pyc +*.pyo +*.pyd +.Python +*.py[cod] +*$py.class +.pytest_cache/ +..mypy_cache/ + +# poetry +.venv + +# C extensions +*.so + +# Virtual environment +.venv +venv + +.DS_Store +.AppleDouble +.LSOverride +._* diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7f578f1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,24 @@ +# Check http://editorconfig.org for more information +# This is the main config file for this project: +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +[*.{py, pyi}] +indent_style = space +indent_size = 4 + +[Makefile] +indent_style = tab + +[*.md] +trim_trailing_whitespace = false + +[*.{diff,patch}] +trim_trailing_whitespace = false diff --git a/.github/.stale.yml b/.github/.stale.yml new file mode 100644 index 0000000..dc90e5a --- /dev/null +++ b/.github/.stale.yml @@ -0,0 +1,17 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 60 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security +# Label to use when marking an issue as stale +staleLabel: wontfix +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..bdd7677 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,42 @@ +--- +name: π Bug report +about: If something isn't working π§ +title: '' +labels: bug +assignees: +--- + +## π Bug Report + + + +## π¬ How To Reproduce + +Steps to reproduce the behavior: + +1. ... + +### Code sample + + + +### Environment + +* OS: [e.g. Linux / Windows / macOS] +* Python version, get it with: + +```bash +python --version +``` + +### Screenshots + + + +## π Expected behavior + + + +## π Additional context + + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..8f2da54 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,3 @@ +# Configuration: https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository + +blank_issues_enabled: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..c387120 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,23 @@ +--- +name: π Feature request +about: Suggest an idea for this project π +title: '' +labels: enhancement +assignees: +--- + +## π Feature Request + + + +## π Motivation + + + +## π° Alternatives + + + +## π Additional context + + diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 0000000..e58d70c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,25 @@ +--- +name: β Question +about: Ask a question about this project π +title: '' +labels: question +assignees: +--- + +## Checklist + + + +- [ ] I've searched the project's [`issues`](https://github.com/chaoqing/PyCXpress/issues?q=is%3Aissue). + +## β Question + + + +How can I [...]? + +Is it possible to [...]? + +## π Additional context + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..34d0416 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,28 @@ +## Description + + + +## Related Issue + + + +## Type of Change + + + +- [ ] π Examples / docs / tutorials / dependencies update +- [ ] π§ Bug fix (non-breaking change which fixes an issue) +- [ ] π₯ Improvement (non-breaking change which improves an existing feature) +- [ ] π New feature (non-breaking change which adds functionality) +- [ ] π₯ Breaking change (fix or feature that would cause existing functionality to change) +- [ ] π Security fix + +## Checklist + + + +- [ ] I've read the [`CODE_OF_CONDUCT.md`](https://github.com/chaoqing/PyCXpress/blob/master/CODE_OF_CONDUCT.md) document. +- [ ] I've read the [`CONTRIBUTING.md`](https://github.com/chaoqing/PyCXpress/blob/master/CONTRIBUTING.md) guide. +- [ ] I've updated the code style using `make codestyle`. +- [ ] I've written tests for all new methods and classes that I created. +- [ ] I've written the docstring in Google format for all the methods and classes that I used. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..3decb07 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,25 @@ +# Configuration: https://dependabot.com/docs/config-file/ +# Docs: https://docs.github.com/en/github/administering-a-repository/keeping-your-dependencies-updated-automatically + +version: 2 + +updates: + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "monthly" + allow: + - dependency-type: "all" + commit-message: + prefix: ":arrow_up:" + open-pull-requests-limit: 5 + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + allow: + - dependency-type: "all" + commit-message: + prefix: ":arrow_up:" + open-pull-requests-limit: 5 \ No newline at end of file diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 0000000..0ce0984 --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,28 @@ +# Release drafter configuration https://github.com/release-drafter/release-drafter#configuration +# Emojis were chosen to match the https://gitmoji.carloscuesta.me/ + +name-template: "v$NEXT_PATCH_VERSION" +tag-template: "v$NEXT_PATCH_VERSION" + +categories: + - title: ":rocket: Features" + labels: [enhancement, feature] + - title: ":wrench: Fixes & Refactoring" + labels: [bug, refactoring, bugfix, fix] + - title: ":package: Build System & CI/CD" + labels: [build, ci, testing] + - title: ":boom: Breaking Changes" + labels: [breaking] + - title: ":pencil: Documentation" + labels: [documentation] + - title: ":arrow_up: Dependencies updates" + labels: [dependencies] + +template: | + ## Whatβs Changed + + $CHANGES + + ## :busts_in_silhouette: List of contributors + + $CONTRIBUTORS diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..7f8742f --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,42 @@ +name: build + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.8", "3.9"] + + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5.1.0 + with: + python-version: ${{ matrix.python-version }} + + - name: Install poetry + run: make poetry-download + + - name: Set up cache + uses: actions/cache@v4.0.2 + with: + path: .venv + key: venv-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }}-${{ hashFiles('poetry.lock') }} + - name: Install dependencies + run: | + poetry config virtualenvs.in-project true + poetry install + + - name: Run style checks + run: | + make check-codestyle + + - name: Run tests + run: | + make test + + - name: Run safety checks + run: | + make check-safety diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml new file mode 100644 index 0000000..a1f6e89 --- /dev/null +++ b/.github/workflows/greetings.yml @@ -0,0 +1,16 @@ +name: Greetings + +on: [pull_request, issues] + +jobs: + greeting: + runs-on: ubuntu-latest + steps: + - uses: actions/first-interaction@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + pr-message: 'Hello @${{ github.actor }}, thank you for submitting a PR! We will respond as soon as possible.' + issue-message: | + Hello @${{ github.actor }}, thank you for your interest in our work! + + If this is a bug report, please provide screenshots and **minimum viable code to reproduce your issue**, otherwise we can not help you. diff --git a/.github/workflows/publish-to-pypi.yml b/.github/workflows/publish-to-pypi.yml new file mode 100644 index 0000000..84216a1 --- /dev/null +++ b/.github/workflows/publish-to-pypi.yml @@ -0,0 +1,52 @@ +name: Publish package + +on: + release: + types: [created] + +jobs: + release-build: + if: github.event_name == 'release' && github.event.action == 'created' + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.11"] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5.1.0 + with: + python-version: ${{ matrix.python-version }} + + - name: Install build + run: python3 -m pip install --upgrade build + + - name: Build release distributions + run: | + python3 -m build --outdir dist/ + + - name: Upload dists + uses: actions/upload-artifact@v4 + with: + name: release-dists + path: dist/ + + pypi-publish: + runs-on: ubuntu-latest + needs: + - release-build + permissions: + id-token: write + + steps: + - name: Retrieve release distributions + uses: actions/download-artifact@v4 + with: + name: release-dists + path: dist/ + + - name: Publish release distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + \ No newline at end of file diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml new file mode 100644 index 0000000..7fb0ef1 --- /dev/null +++ b/.github/workflows/release-drafter.yml @@ -0,0 +1,16 @@ +name: Release Drafter + +on: + push: + # branches to consider in the event; optional, defaults to all + branches: + - master + +jobs: + update_release_draft: + runs-on: ubuntu-latest + steps: + # Drafts your next Release notes as Pull Requests are merged into "master" + - uses: release-drafter/release-drafter@v6.0.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 259148f..0a2ef70 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,7 @@ *.exe *.out *.app + +# Python +dist/ +__pycache__/ \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..85d266f --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,36 @@ +default_language_version: + python: python3.8 + +default_stages: [commit, push] + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.5.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + exclude: LICENSE + + - repo: local + hooks: + - id: pyupgrade + name: pyupgrade + entry: poetry run pyupgrade --py38-plus + types: [python] + language: system + + - repo: local + hooks: + - id: isort + name: isort + entry: poetry run isort --settings-path pyproject.toml + types: [python] + language: system + + - repo: local + hooks: + - id: black + name: black + entry: poetry run black --config pyproject.toml + types: [python] + language: system diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..716f26c --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at chaoqingwang.nick@gmail.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..16e880e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,47 @@ +# How to contribute + +## Dependencies + +We use `poetry` to manage the [dependencies](https://github.com/python-poetry/poetry). +If you dont have `poetry`, you should install with `make poetry-download`. + +To install dependencies and prepare [`pre-commit`](https://pre-commit.com/) hooks you would need to run `install` command: + +```bash +make install +make pre-commit-install +``` + +To activate your `virtualenv` run `poetry shell`. + +## Codestyle + +After installation you may execute code formatting. + +```bash +make codestyle +``` + +### Checks + +Many checks are configured for this project. Command `make check-codestyle` will check black, isort and darglint. +The `make check-safety` command will look at the security of your code. + +Comand `make lint` applies all checks. + +### Before submitting + +Before submitting your code please do the following steps: + +1. Add any changes you want +1. Add tests for the new changes +1. Edit documentation if you have changed something significant +1. Run `make codestyle` to format your changes. +1. Run `make lint` to ensure that types, security and docstrings are okay. + +## Other help + +You can contribute by spreading a word about this library. +It would also be a huge contribution to write +a short article on how you are using this project. +You can also share your best practices with us. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..421882e --- /dev/null +++ b/Makefile @@ -0,0 +1,113 @@ +#* Variables +SHELL := /usr/bin/env bash +PYTHON := python +PYTHONPATH := `pwd` + +#* Docker variables +IMAGE := PyCXpress +VERSION := latest + +#* Poetry +.PHONY: poetry-download +poetry-download: + curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/install-poetry.py | $(PYTHON) - + +.PHONY: poetry-remove +poetry-remove: + curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/install-poetry.py | $(PYTHON) - --uninstall + +#* Installation +.PHONY: install +install: + poetry lock -n && poetry export --without-hashes > requirements.txt + poetry install -n + -poetry run mypy --install-types --non-interactive ./ + +.PHONY: pre-commit-install +pre-commit-install: + poetry run pre-commit install + +#* Formatters +.PHONY: codestyle +codestyle: + poetry run pyupgrade --exit-zero-even-if-changed --py38-plus **/*.py + poetry run isort --settings-path pyproject.toml ./ + poetry run black --config pyproject.toml ./ + +.PHONY: formatting +formatting: codestyle + +#* Linting +.PHONY: test +test: + PYTHONPATH=$(PYTHONPATH) poetry run pytest -c pyproject.toml --cov-report=html --cov=PyCXpress tests/ + poetry run coverage-badge -o assets/images/coverage.svg -f + +.PHONY: check-codestyle +check-codestyle: + poetry run isort --diff --check-only --settings-path pyproject.toml ./ + poetry run black --diff --check --config pyproject.toml ./ + poetry run darglint --verbosity 2 PyCXpress tests + +.PHONY: mypy +mypy: + poetry run mypy --config-file pyproject.toml ./ + +.PHONY: check-safety +check-safety: + poetry check + poetry run safety check --full-report + poetry run bandit -ll --recursive PyCXpress tests + +.PHONY: lint +lint: test check-codestyle mypy check-safety + +.PHONY: update-dev-deps +update-dev-deps: + poetry add -D bandit@latest darglint@latest "isort[colors]@latest" mypy@latest pre-commit@latest pydocstyle@latest pylint@latest pytest@latest pyupgrade@latest safety@latest coverage@latest coverage-badge@latest pytest-html@latest pytest-cov@latest + poetry add -D --allow-prereleases black@latest + +#* Docker +# Example: make docker-build VERSION=latest +# Example: make docker-build IMAGE=some_name VERSION=0.0.1 +.PHONY: docker-build +docker-build: + @echo Building docker $(IMAGE):$(VERSION) ... + docker build \ + -t $(IMAGE):$(VERSION) . \ + -f ./docker/Dockerfile --no-cache + +# Example: make docker-remove VERSION=latest +# Example: make docker-remove IMAGE=some_name VERSION=0.0.1 +.PHONY: docker-remove +docker-remove: + @echo Removing docker $(IMAGE):$(VERSION) ... + docker rmi -f $(IMAGE):$(VERSION) + +#* Cleaning +.PHONY: pycache-remove +pycache-remove: + find . | grep -E "(__pycache__|\.pyc|\.pyo$$)" | xargs rm -rf + +.PHONY: dsstore-remove +dsstore-remove: + find . | grep -E ".DS_Store" | xargs rm -rf + +.PHONY: mypycache-remove +mypycache-remove: + find . | grep -E ".mypy_cache" | xargs rm -rf + +.PHONY: ipynbcheckpoints-remove +ipynbcheckpoints-remove: + find . | grep -E ".ipynb_checkpoints" | xargs rm -rf + +.PHONY: pytestcache-remove +pytestcache-remove: + find . | grep -E ".pytest_cache" | xargs rm -rf + +.PHONY: build-remove +build-remove: + rm -rf build/ + +.PHONY: cleanup +cleanup: pycache-remove dsstore-remove mypycache-remove ipynbcheckpoints-remove pytestcache-remove diff --git a/README.md b/README.md index 67f13c6..a3ad560 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,37 @@ # PyCXpress + +