diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4aafe62..cb42977 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -199,7 +199,7 @@ jobs: git tag -l --sort=-taggerdate:iso --format="$GIT_LOG_FORMAT" >>CHANGELOG.md git tag -l --sort=-taggerdate:iso --format="$GIT_LOG_FORMAT" >>docs/changelog.md - name: Format changelog with Prettier - run: npx -s -y prettier@'^3' --write CHANGELOG.md docs/changelog.md + run: npx -s -y prettier@'^3.4' --write CHANGELOG.md docs/changelog.md - name: Create pull request with updated changelog uses: peter-evans/create-pull-request@v6 with: diff --git a/docs/changelog.md b/docs/changelog.md index 405528b..96d7b5d 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -17,25 +17,25 @@ updating to 3.9 or above. ### Commits -- Bump version from 0.5.0 to 0.6.0 (a6aa08e) -- Upgrade syntax after dropping Python 3.8 (6ca4c1b) -- Drop Python 3.8 support (a8a4c59) -- Update test dependencies for FastAPI 0.115 (9a164e2) -- Update to Ruff 0.6 (d02e241) -- Update to `mypy==1.11.2` (a601145) -- Update to `pipx==1.7.1` (75b589d) -- Update to FastAPI 0.112 (8bc5f5d) -- Don't hard-code repo name in GitHub Actions jobs (6ac42e3) -- Use dedicated GitHub Actions job for PyPI (d0e973c) -- Update to `hatch==1.12.0` (a80ba80) -- Update to `pipx==1.6.0` (025443a) -- Update to `mypy==1.10.1` (6faaadf) -- Update to Ruff 0.5 (816d464) -- Update to Prettier 3 (fc811c5) -- Update to FastAPI 0.111 (984db1f) -- Add project background link to README (34e5b94) -- Add suggested pronounciation to README (4dedbf9) -- Update changelog for version 0.5.0 (#33) (6bb820c) +- Bump version from 0.5.0 to 0.6.0 (a6aa08e) +- Upgrade syntax after dropping Python 3.8 (6ca4c1b) +- Drop Python 3.8 support (a8a4c59) +- Update test dependencies for FastAPI 0.115 (9a164e2) +- Update to Ruff 0.6 (d02e241) +- Update to `mypy==1.11.2` (a601145) +- Update to `pipx==1.7.1` (75b589d) +- Update to FastAPI 0.112 (8bc5f5d) +- Don't hard-code repo name in GitHub Actions jobs (6ac42e3) +- Use dedicated GitHub Actions job for PyPI (d0e973c) +- Update to `hatch==1.12.0` (a80ba80) +- Update to `pipx==1.6.0` (025443a) +- Update to `mypy==1.10.1` (6faaadf) +- Update to Ruff 0.5 (816d464) +- Update to Prettier 3 (fc811c5) +- Update to FastAPI 0.111 (984db1f) +- Add project background link to README (34e5b94) +- Add suggested pronounciation to README (4dedbf9) +- Update changelog for version 0.5.0 (#33) (6bb820c) Tagger: Brendon Smith @@ -100,19 +100,19 @@ This release will add [Python 3.12](https://docs.python.org/3/whatsnew/3.12.html) support to fastenv. -- fastenv will now include a Python 3.12 classifier in its PyPI package -- fastenv will now build and publish its PyPI package using Python 3.12 -- fastenv will now run tests with Python 3.12, in addition to 3.8-3.11 +- fastenv will now include a Python 3.12 classifier in its PyPI package +- fastenv will now build and publish its PyPI package using Python 3.12 +- fastenv will now run tests with Python 3.12, in addition to 3.8-3.11 ### Commits -- Bump version from 0.4.2 to 0.5.0 (26fd927) -- Document and test FastAPI integration (#32) (7362541) -- Update to pytest 8 (1e8b896) -- Update path to contributing.md in PR template (d51c035) -- Update contact info in code of conduct (41bc76c) -- Add support for Python 3.12 (#31) (5346486) -- Update changelog for version 0.4.2 (#30) (ed436f9) +- Bump version from 0.4.2 to 0.5.0 (26fd927) +- Document and test FastAPI integration (#32) (7362541) +- Update to pytest 8 (1e8b896) +- Update path to contributing.md in PR template (d51c035) +- Update contact info in code of conduct (41bc76c) +- Add support for Python 3.12 (#31) (5346486) +- Update changelog for version 0.4.2 (#30) (ed436f9) Tagger: Brendon Smith @@ -146,10 +146,10 @@ unique URL. ### Commits -- Bump version from 0.4.1 to 0.4.2 (ff9d56f) -- Avoid auto-inactivating GitHub Actions deployments (6d6f5c9) -- Reset `peter-evans/create-pull-request@v6` author (845e8b2) -- Update changelog for version 0.4.1 (#29) (b60a73d) +- Bump version from 0.4.1 to 0.4.2 (ff9d56f) +- Avoid auto-inactivating GitHub Actions deployments (6d6f5c9) +- Reset `peter-evans/create-pull-request@v6` author (845e8b2) +- Update changelog for version 0.4.1 (#29) (b60a73d) Tagger: Brendon Smith @@ -210,18 +210,18 @@ pypa/gh-action-pypi-publish@release/v1.8. ### Commits -- Bump version from 0.4.0 to 0.4.1 (d668549) -- Publish to PyPI with OIDC trusted publisher (6e532c6) -- Update to `peter-evans/create-pull-request@v6` (0918b9e) -- Add support for AnyIO 4 (b33e84e) -- Update to Ruff 0.3 (658fb4b) -- Update to `mypy==1.9.0` (64adf48) -- Update to `hatch==1.9.4` (6c60f7e) -- Update to `pipx==1.5.0` (795e1d2) -- Update comparisons docs for Starlette 0.37 (99e233f) -- Disable CodeQL `setup-python-dependencies` (11d8d60) -- Update to Node.js 20 actions (a6d2e06) -- Update changelog for version 0.4.0 (#27) (649cc4c) +- Bump version from 0.4.0 to 0.4.1 (d668549) +- Publish to PyPI with OIDC trusted publisher (6e532c6) +- Update to `peter-evans/create-pull-request@v6` (0918b9e) +- Add support for AnyIO 4 (b33e84e) +- Update to Ruff 0.3 (658fb4b) +- Update to `mypy==1.9.0` (64adf48) +- Update to `hatch==1.9.4` (6c60f7e) +- Update to `pipx==1.5.0` (795e1d2) +- Update comparisons docs for Starlette 0.37 (99e233f) +- Disable CodeQL `setup-python-dependencies` (11d8d60) +- Update to Node.js 20 actions (a6d2e06) +- Update changelog for version 0.4.0 (#27) (649cc4c) Tagger: Brendon Smith @@ -278,44 +278,44 @@ will be migrated from the previous tools (Black, Flake8, isort) to Ruff. ### Commits -- Bump version from 0.3.0 to 0.4.0 (620af5e) -- Add support for Cloudflare R2 object storage (#26) (6b06299) -- Add PUT uploads to object storage client (#25) (6968353) -- Remove trailing slash from `bucket_host` (8492656) -- Update test info in CONTRIBUTING.md (69bdf05) -- Update to `peter-evans/create-pull-request@v5` (4ddb5b5) -- Update to `aws-actions/configure-aws-credentials@v4` (e59316e) -- Update to `actions/checkout@v4` (ebdea31) -- Update CodeQL workflow actions (03e80cc) -- Address CodeQL URL substring sanitization error (a822a86) -- Remove scheme from `bucket_host` (aaf3f1d) -- Remove curly quote (0f2c1bb) -- Use Ruff for linting and formatting (e635c33) -- Add wheel build target to avoid Hatch `ValueError` (a7fffb7) -- Update to `pipx==1.4.1` (a53eb2b) -- Update to `mypy==1.8.0` (16c6329) -- Update to `hatch==1.9.1` (2ab4bff) -- Update to `pipx==1.4.0` (31c9854) -- Update to `pipx==1.3.3` (f5ddd6d) -- Remove unneeded stale workflow (d86b4ba) -- Switch from pre-commit to Hatch scripts (0f60779) -- Finish configuring code block copy (34fbe9a) -- Add docs deployment info to contributing.md (70b358e) -- Remove Material for MkDocs version from README (380f364) -- Configure Material for MkDocs code block copy (5c8b6ea) -- Update to Material for MkDocs 9 (a1349d4) -- Relax upper bound on HTTPX (ab0e909) -- Update to `mypy==1.7.0` (27549f5) -- Prepend `$HATCH_ENV` in GitHub Actions workflow (c5cf02d) -- Update to `hatch==1.7.0` (d8ee4e6) -- Remove Sourcery configuration file (9f61678) -- Update Black in pre-commit (6fd48d6) -- Update to `mypy==1.3.0` (e1a0e09) -- Update to coverage 7 (8702743) -- Update to `pipx==1.2.0` (dcbe73b) -- Update to mypy 1.1.1 (f666fdb) -- Update to configure-aws-credentials@v2 (5d20126) -- Update changelog for version 0.3.0 (#23) (d13a924) +- Bump version from 0.3.0 to 0.4.0 (620af5e) +- Add support for Cloudflare R2 object storage (#26) (6b06299) +- Add PUT uploads to object storage client (#25) (6968353) +- Remove trailing slash from `bucket_host` (8492656) +- Update test info in CONTRIBUTING.md (69bdf05) +- Update to `peter-evans/create-pull-request@v5` (4ddb5b5) +- Update to `aws-actions/configure-aws-credentials@v4` (e59316e) +- Update to `actions/checkout@v4` (ebdea31) +- Update CodeQL workflow actions (03e80cc) +- Address CodeQL URL substring sanitization error (a822a86) +- Remove scheme from `bucket_host` (aaf3f1d) +- Remove curly quote (0f2c1bb) +- Use Ruff for linting and formatting (e635c33) +- Add wheel build target to avoid Hatch `ValueError` (a7fffb7) +- Update to `pipx==1.4.1` (a53eb2b) +- Update to `mypy==1.8.0` (16c6329) +- Update to `hatch==1.9.1` (2ab4bff) +- Update to `pipx==1.4.0` (31c9854) +- Update to `pipx==1.3.3` (f5ddd6d) +- Remove unneeded stale workflow (d86b4ba) +- Switch from pre-commit to Hatch scripts (0f60779) +- Finish configuring code block copy (34fbe9a) +- Add docs deployment info to contributing.md (70b358e) +- Remove Material for MkDocs version from README (380f364) +- Configure Material for MkDocs code block copy (5c8b6ea) +- Update to Material for MkDocs 9 (a1349d4) +- Relax upper bound on HTTPX (ab0e909) +- Update to `mypy==1.7.0` (27549f5) +- Prepend `$HATCH_ENV` in GitHub Actions workflow (c5cf02d) +- Update to `hatch==1.7.0` (d8ee4e6) +- Remove Sourcery configuration file (9f61678) +- Update Black in pre-commit (6fd48d6) +- Update to `mypy==1.3.0` (e1a0e09) +- Update to coverage 7 (8702743) +- Update to `pipx==1.2.0` (dcbe73b) +- Update to mypy 1.1.1 (f666fdb) +- Update to configure-aws-credentials@v2 (5d20126) +- Update changelog for version 0.3.0 (#23) (d13a924) Tagger: Brendon Smith @@ -340,9 +340,9 @@ This release will add [Python 3.11](https://docs.python.org/3/whatsnew/3.11.html) support to fastenv. -- fastenv will now include a Python 3.11 classifier in its PyPI package -- fastenv will now build and publish its PyPI package using Python 3.11 -- fastenv will now run tests with Python 3.11, in addition to 3.8-3.10 +- fastenv will now include a Python 3.11 classifier in its PyPI package +- fastenv will now build and publish its PyPI package using Python 3.11 +- fastenv will now run tests with Python 3.11, in addition to 3.8-3.10 **Migrate from Poetry 1.1 to Hatch** (#14, f0c6882, 78755e7, e2f8d04, 85b8e79, 903a7de) @@ -371,31 +371,31 @@ The contributing.md will be updated with instructions for type checking. `0.2.5..0.3.0` -- Bump version from 0.3.0-beta.0 to 0.3.0 (2864bee) -- Update to mypy 1 (4df9eac) -- Update to Black 23 (bccad2c) -- Update isort to avoid poetry-core breaking change (e417e07) -- Update changelog for version 0.3.0-beta.0 (#22) (f6f2ce9) -- Bump version from 0.3.0-alpha.0 to 0.3.0-beta.0 (cc56f8d) -- Fix upper bound on HTTPX optional dependency (903a7de) -- Alphabetize Hatch commands in contributing.md (85b8e79) -- Regroup testing info in contributing.md (e2f8d04) -- Remove PEP 631 references from README (4f1e57c) -- Add trailing comma to `pyproject.toml` classifiers (78755e7) -- Alphabetize fields in `pyproject.toml` (f0c6882) -- Update changelog for version 0.3.0-alpha.0 (#16) (69487f9) -- Bump version from 0.2.5 to 0.3.0-alpha.0 (f83b3e0) -- Add Python 3.11 support (#15) (0fcbc5f) -- Remove unused `.prettierrc` (6d2c8c3) -- Merge pull request #14 from br3ndonland/hatch (801e256) -- Update docs for Hatch (3e7e049) -- Update GitHub Actions workflows for Hatch (e5fb5d6) -- Update configuration files for Hatch (5d409be) -- Add spell check with CSpell (e2df8c0) -- Auto-generate changelog from Git tags (c7aa765) -- Enable mypy strict mode (7fbb89f) -- Update pre-commit dependencies (8324d2c) -- Update dependencies (2d0793c) +- Bump version from 0.3.0-beta.0 to 0.3.0 (2864bee) +- Update to mypy 1 (4df9eac) +- Update to Black 23 (bccad2c) +- Update isort to avoid poetry-core breaking change (e417e07) +- Update changelog for version 0.3.0-beta.0 (#22) (f6f2ce9) +- Bump version from 0.3.0-alpha.0 to 0.3.0-beta.0 (cc56f8d) +- Fix upper bound on HTTPX optional dependency (903a7de) +- Alphabetize Hatch commands in contributing.md (85b8e79) +- Regroup testing info in contributing.md (e2f8d04) +- Remove PEP 631 references from README (4f1e57c) +- Add trailing comma to `pyproject.toml` classifiers (78755e7) +- Alphabetize fields in `pyproject.toml` (f0c6882) +- Update changelog for version 0.3.0-alpha.0 (#16) (69487f9) +- Bump version from 0.2.5 to 0.3.0-alpha.0 (f83b3e0) +- Add Python 3.11 support (#15) (0fcbc5f) +- Remove unused `.prettierrc` (6d2c8c3) +- Merge pull request #14 from br3ndonland/hatch (801e256) +- Update docs for Hatch (3e7e049) +- Update GitHub Actions workflows for Hatch (e5fb5d6) +- Update configuration files for Hatch (5d409be) +- Add spell check with CSpell (e2df8c0) +- Auto-generate changelog from Git tags (c7aa765) +- Enable mypy strict mode (7fbb89f) +- Update pre-commit dependencies (8324d2c) +- Update dependencies (2d0793c) Tagger: Brendon Smith @@ -420,9 +420,9 @@ This release will add [Python 3.11](https://docs.python.org/3/whatsnew/3.11.html) support to fastenv. -- fastenv will now include a Python 3.11 classifier in its PyPI package -- fastenv will now build and publish its PyPI package using Python 3.11 -- fastenv will now run tests with Python 3.11, in addition to 3.8-3.10 +- fastenv will now include a Python 3.11 classifier in its PyPI package +- fastenv will now build and publish its PyPI package using Python 3.11 +- fastenv will now run tests with Python 3.11, in addition to 3.8-3.10 **Migrate from Poetry 1.1 to Hatch** (#14, f0c6882, 78755e7, e2f8d04, 85b8e79, 903a7de) @@ -449,26 +449,26 @@ The contributing.md will be updated with instructions for type checking. ### Commits -- Bump version from 0.3.0-alpha.0 to 0.3.0-beta.0 (cc56f8d) -- Fix upper bound on HTTPX optional dependency (903a7de) -- Alphabetize Hatch commands in contributing.md (85b8e79) -- Regroup testing info in contributing.md (e2f8d04) -- Remove PEP 631 references from README (4f1e57c) -- Add trailing comma to `pyproject.toml` classifiers (78755e7) -- Alphabetize fields in `pyproject.toml` (f0c6882) -- Update changelog for version 0.3.0-alpha.0 (#16) (69487f9) -- Bump version from 0.2.5 to 0.3.0-alpha.0 (f83b3e0) -- Add Python 3.11 support (#15) (0fcbc5f) -- Remove unused `.prettierrc` (6d2c8c3) -- Merge pull request #14 from br3ndonland/hatch (801e256) -- Update docs for Hatch (3e7e049) -- Update GitHub Actions workflows for Hatch (e5fb5d6) -- Update configuration files for Hatch (5d409be) -- Add spell check with CSpell (e2df8c0) -- Auto-generate changelog from Git tags (c7aa765) -- Enable mypy strict mode (7fbb89f) -- Update pre-commit dependencies (8324d2c) -- Update dependencies (2d0793c) +- Bump version from 0.3.0-alpha.0 to 0.3.0-beta.0 (cc56f8d) +- Fix upper bound on HTTPX optional dependency (903a7de) +- Alphabetize Hatch commands in contributing.md (85b8e79) +- Regroup testing info in contributing.md (e2f8d04) +- Remove PEP 631 references from README (4f1e57c) +- Add trailing comma to `pyproject.toml` classifiers (78755e7) +- Alphabetize fields in `pyproject.toml` (f0c6882) +- Update changelog for version 0.3.0-alpha.0 (#16) (69487f9) +- Bump version from 0.2.5 to 0.3.0-alpha.0 (f83b3e0) +- Add Python 3.11 support (#15) (0fcbc5f) +- Remove unused `.prettierrc` (6d2c8c3) +- Merge pull request #14 from br3ndonland/hatch (801e256) +- Update docs for Hatch (3e7e049) +- Update GitHub Actions workflows for Hatch (e5fb5d6) +- Update configuration files for Hatch (5d409be) +- Add spell check with CSpell (e2df8c0) +- Auto-generate changelog from Git tags (c7aa765) +- Enable mypy strict mode (7fbb89f) +- Update pre-commit dependencies (8324d2c) +- Update dependencies (2d0793c) Tagger: Brendon Smith @@ -493,9 +493,9 @@ This release will add [Python 3.11](https://docs.python.org/3/whatsnew/3.11.html) support to fastenv. -- fastenv will now include a Python 3.11 classifier in its PyPI package -- fastenv will now build and publish its PyPI package using Python 3.11 -- fastenv will now run tests with Python 3.11, in addition to 3.8-3.10 +- fastenv will now include a Python 3.11 classifier in its PyPI package +- fastenv will now build and publish its PyPI package using Python 3.11 +- fastenv will now run tests with Python 3.11, in addition to 3.8-3.10 **Migrate from Poetry 1.1 to Hatch** (#14) @@ -522,18 +522,18 @@ The contributing.md will be updated with instructions for type checking. Commits: -- Bump version from 0.2.5 to 0.3.0-alpha.0 (f83b3e0) -- Add Python 3.11 support (#15) (0fcbc5f) -- Remove unused `.prettierrc` (6d2c8c3) -- Merge pull request #14 from br3ndonland/hatch (801e256) -- Update docs for Hatch (3e7e049) -- Update GitHub Actions workflows for Hatch (e5fb5d6) -- Update configuration files for Hatch (5d409be) -- Add spell check with CSpell (e2df8c0) -- Auto-generate changelog from Git tags (c7aa765) -- Enable mypy strict mode (7fbb89f) -- Update pre-commit dependencies (8324d2c) -- Update dependencies (2d0793c) +- Bump version from 0.2.5 to 0.3.0-alpha.0 (f83b3e0) +- Add Python 3.11 support (#15) (0fcbc5f) +- Remove unused `.prettierrc` (6d2c8c3) +- Merge pull request #14 from br3ndonland/hatch (801e256) +- Update docs for Hatch (3e7e049) +- Update GitHub Actions workflows for Hatch (e5fb5d6) +- Update configuration files for Hatch (5d409be) +- Add spell check with CSpell (e2df8c0) +- Auto-generate changelog from Git tags (c7aa765) +- Enable mypy strict mode (7fbb89f) +- Update pre-commit dependencies (8324d2c) +- Update dependencies (2d0793c) Tagger: Brendon Smith @@ -552,10 +552,10 @@ AAAAQLxzSE0qq+dNRJKqfdL41qz5Cp4xHW7TNABnxD5bp+Vl0IW+p3XUW85dESWWOMIvo+ Commits: -- Bump version from 0.2.4 to 0.2.5 (92bc9dc) -- Update to Flake8 6 (23503a5) -- Update type annotations for PEP 484 (20eb205) -- Update dependencies (8e99ff4) +- Bump version from 0.2.4 to 0.2.5 (92bc9dc) +- Update to Flake8 6 (23503a5) +- Update type annotations for PEP 484 (20eb205) +- Update dependencies (8e99ff4) Note about Git commit and tag verification: @@ -586,10 +586,10 @@ tgrbY2MHDvnvzKKsfJyAw= Commits: -- Bump version from 0.2.3 to 0.2.4 (e7b5814) -- Update to Flake8 5 (6250255) -- Update dependencies (2c0267c) -- Add changelog command to docs (8162c83) +- Bump version from 0.2.3 to 0.2.4 (e7b5814) +- Update to Flake8 5 (6250255) +- Update dependencies (2c0267c) +- Add changelog command to docs (8162c83) Tagger: Brendon Smith @@ -609,10 +609,10 @@ EKdvP0VjjRFvVezFpNmThiDTa9z1hAA= Commits: -- Bump version from 0.2.2 to 0.2.3 (42af2d0) -- Update stale workflow (d8eedbd) -- Update to pipx 1.1.0 (0ca9a9e) -- Update dependencies (2ec067b) +- Bump version from 0.2.2 to 0.2.3 (42af2d0) +- Update stale workflow (d8eedbd) +- Update to pipx 1.1.0 (0ca9a9e) +- Update dependencies (2ec067b) Tagger: Brendon Smith @@ -632,20 +632,20 @@ KasWTLD5GOcLWjvHy7HtSppeRunF/AI= Commits: -- Bump version from 0.2.1 to 0.2.2 (0fddd80) -- Update to HTTPX 0.23 (fb4fa0b) -- Update dependencies (b6b6e59) -- Update CodeQL workflow actions (bf9d0da) -- Merge pull request #12 from br3ndonland/drop-codecov (dde5d74) -- Specify source files for coverage.py (fca4234) -- Fix inadvertent pytest fixture session token usage (5532293) -- Run pytest with coverage.py in GitHub Actions (962458c) -- Raise coverage of tests to 100% (82a7866) -- Remove pytest-cov and just use coverage.py (fd29a0f) -- Remove Codecov upload from GitHub Actions workflow (8b464e6) -- Add shields.io badge for test coverage (df03d14) -- Remove Codecov badge from README (e832aa5) -- Remove Codecov YAML (a834fac) +- Bump version from 0.2.1 to 0.2.2 (0fddd80) +- Update to HTTPX 0.23 (fb4fa0b) +- Update dependencies (b6b6e59) +- Update CodeQL workflow actions (bf9d0da) +- Merge pull request #12 from br3ndonland/drop-codecov (dde5d74) +- Specify source files for coverage.py (fca4234) +- Fix inadvertent pytest fixture session token usage (5532293) +- Run pytest with coverage.py in GitHub Actions (962458c) +- Raise coverage of tests to 100% (82a7866) +- Remove pytest-cov and just use coverage.py (fd29a0f) +- Remove Codecov upload from GitHub Actions workflow (8b464e6) +- Add shields.io badge for test coverage (df03d14) +- Remove Codecov badge from README (e832aa5) +- Remove Codecov YAML (a834fac) Tagger: Brendon Smith @@ -669,12 +669,12 @@ Enforce presigned URL min and max expiration times (6c75a76) Commits: -- Bump version from 0.2.0 to 0.2.1 (ef91d53) -- Update to v3 actions (b546cb6) -- Enforce presigned URL min and max expiration times (6c75a76) -- Add Sourcery config file to set Python version (a0f0a34) -- Update dependencies (c947c21) -- Update to codecov/codecov-action@v3 (99b2b65) +- Bump version from 0.2.0 to 0.2.1 (ef91d53) +- Update to v3 actions (b546cb6) +- Enforce presigned URL min and max expiration times (6c75a76) +- Add Sourcery config file to set Python version (a0f0a34) +- Update dependencies (c947c21) +- Update to codecov/codecov-action@v3 (99b2b65) Tagger: Brendon Smith @@ -698,26 +698,26 @@ Integrate with object storage (#8) Commits: -- Bump version from 0.1.4 to 0.2.0 (f752d31) -- Update to pytest 7 (4a76b69) -- Update dependencies (be473b7) -- Merge pull request #8 from br3ndonland/object-storage (b06add0) -- Remove extra Material for MkDocs annotations (9e349e8) -- Address CodeQL URL substring sanitization error (6156a2d) -- Refactor #8 with Sourcery (#9) (a34b9be) -- Move object storage code to `fastenv.cloud` (8d70777) -- Implement object storage client directly (835801d) -- Update Black to resolve pre-commit `ImportError` (a63fe07) -- Remove `aioaws` from dependencies (ca9a39f) -- Integrate with object storage using `aioaws` (7bfbd8f) -- Add `aioaws` to dependencies (2bb9514) -- Add quickstart section to README (2574865) -- Update to Material for MkDocs 8 (334b793) -- Update dependencies (f2b10d5) -- Simplify `DotEnv._sort_dotenv` comprehension (24664e6) -- Add default filename to `load_dotenv` docs (a956e44) -- Update dependencies (74f0209) -- Add missing token permissions to CodeQL workflow (319cd50) +- Bump version from 0.1.4 to 0.2.0 (f752d31) +- Update to pytest 7 (4a76b69) +- Update dependencies (be473b7) +- Merge pull request #8 from br3ndonland/object-storage (b06add0) +- Remove extra Material for MkDocs annotations (9e349e8) +- Address CodeQL URL substring sanitization error (6156a2d) +- Refactor #8 with Sourcery (#9) (a34b9be) +- Move object storage code to `fastenv.cloud` (8d70777) +- Implement object storage client directly (835801d) +- Update Black to resolve pre-commit `ImportError` (a63fe07) +- Remove `aioaws` from dependencies (ca9a39f) +- Integrate with object storage using `aioaws` (7bfbd8f) +- Add `aioaws` to dependencies (2bb9514) +- Add quickstart section to README (2574865) +- Update to Material for MkDocs 8 (334b793) +- Update dependencies (f2b10d5) +- Simplify `DotEnv._sort_dotenv` comprehension (24664e6) +- Add default filename to `load_dotenv` docs (a956e44) +- Update dependencies (74f0209) +- Add missing token permissions to CodeQL workflow (319cd50) Tagger: Brendon Smith @@ -735,17 +735,17 @@ NgjHVX6BV0uAMrE7MBByNq2MuFjY0gg= ## 0.1.4 - 2021-11-09 -- Bump version from 0.1.3 to 0.1.4 (8302177) -- Refactor test data into parametrized fixtures (044be0a) -- Remove remaining uses of `example_dict` from tests (9d9b0d7) -- Allow deletion of empty variables from `DotEnv`s (cb728f9) -- Organize repetitive assertion into helper method (9e74aa3) -- Use `items()` to directly unpack dictionary values (41990df) -- Update dependencies (f334af9) -- Test package version before publishing to PyPI (935f081) -- Test Poetry virtualenv location (67c375b) -- Disable Poetry experimental new installer (bd58436) -- Add push triggers back to CodeQL workflow (861f16e) +- Bump version from 0.1.3 to 0.1.4 (8302177) +- Refactor test data into parametrized fixtures (044be0a) +- Remove remaining uses of `example_dict` from tests (9d9b0d7) +- Allow deletion of empty variables from `DotEnv`s (cb728f9) +- Organize repetitive assertion into helper method (9e74aa3) +- Use `items()` to directly unpack dictionary values (41990df) +- Update dependencies (f334af9) +- Test package version before publishing to PyPI (935f081) +- Test Poetry virtualenv location (67c375b) +- Disable Poetry experimental new installer (bd58436) +- Add push triggers back to CodeQL workflow (861f16e) Tagger: Brendon Smith @@ -763,24 +763,24 @@ eGlyAPkBRftCYGpfY2NMw40sH6oyQeVDG5WOVlhYl4AQwiNj1QEAmcoM/6L5+++m ## 0.1.3 - 2021-10-23 -- Bump version from 0.1.2 to 0.1.3 (4489b5d) -- Update dependencies (15e35a0) -- Merge pull request #7 from br3ndonland/python-3.10 (2ea05a4) - Add Python 3.10 support -- Add Python 3.10 to GitHub Actions workflow (1a2e46b) -- Merge pull request #6 from br3ndonland/poetry-version (b9d417b) - Pin and test Poetry version -- Pin and test Poetry version (ed7c8d2) -- Update Codecov YAML Boolean syntax (47065f8) -- Rename AWS credentials in docs and tests (908dfcf) -- Add PEP 621 and PEP 631 links to docs (de08de9) -- Clarify limitations of `os.environ` in comparisons (c1c8605) -- Update dependencies (b55defb) -- Remove `find_dotenv(starting_dir)` docs reference (753f529) -- Update dependencies (a16595d) -- Disable Git LFS for images for Vercel deployment (cbeab06) -- Use heroicons cog as favicon (80878b7) -- Add missing MkDocs favicon config (b60a4b5) +- Bump version from 0.1.2 to 0.1.3 (4489b5d) +- Update dependencies (15e35a0) +- Merge pull request #7 from br3ndonland/python-3.10 (2ea05a4) + Add Python 3.10 support +- Add Python 3.10 to GitHub Actions workflow (1a2e46b) +- Merge pull request #6 from br3ndonland/poetry-version (b9d417b) + Pin and test Poetry version +- Pin and test Poetry version (ed7c8d2) +- Update Codecov YAML Boolean syntax (47065f8) +- Rename AWS credentials in docs and tests (908dfcf) +- Add PEP 621 and PEP 631 links to docs (de08de9) +- Clarify limitations of `os.environ` in comparisons (c1c8605) +- Update dependencies (b55defb) +- Remove `find_dotenv(starting_dir)` docs reference (753f529) +- Update dependencies (a16595d) +- Disable Git LFS for images for Vercel deployment (cbeab06) +- Use heroicons cog as favicon (80878b7) +- Add missing MkDocs favicon config (b60a4b5) Tagger: Brendon Smith @@ -798,12 +798,12 @@ eE0oAQCtjzZ/h8ZtGrJV8lKHrRAThgsd9fWAt8zhb4ovegUEmgD5Ab6kkH6527C+ ## 0.1.2 - 2021-08-06 -- Bump version from 0.1.1 to 0.1.2 (8b3115c) -- Update dependencies (87706d6) -- Implement `DotEnv` sorting (0f77ee3) -- Test `find_dotenv` on resolved paths and filenames (aec7672) -- Clean up `load_dotenv` tests (043626a) -- Add missing `test_` prefix to `dump_dotenv` test (dea4ef4) +- Bump version from 0.1.1 to 0.1.2 (8b3115c) +- Update dependencies (87706d6) +- Implement `DotEnv` sorting (0f77ee3) +- Test `find_dotenv` on resolved paths and filenames (aec7672) +- Clean up `load_dotenv` tests (043626a) +- Add missing `test_` prefix to `dump_dotenv` test (dea4ef4) Tagger: Brendon Smith @@ -821,18 +821,18 @@ EwTBNJ5M8YyedUU6tHHFEUUKPycqsgY= ## 0.1.1 - 2021-08-01 -- Bump version from 0.1.0 to 0.1.1 (597590f) -- Update dependencies (c5dbdaf) -- Merge pull request #5 from br3ndonland/load_dotenv_multi (796e10c) - Load multiple .env files with `load_dotenv` -- Refactor `load_dotenv` into smaller methods (74ca273) -- Organize repetitive assertions with helper methods (b1c8c72) -- Add missing `from __future__ import annotations` (83b7696) -- Document how to load multiple .env files (07cfa3b) -- Load multiple .env files with `load_dotenv` (0813a5e) -- Simplify `venv` code blocks in docs (400cb3e) -- Drop "Development Status" PyPI trove classifier (a5188d1) -- Correct `find_dotenv` docstring typo (d42fd15) +- Bump version from 0.1.0 to 0.1.1 (597590f) +- Update dependencies (c5dbdaf) +- Merge pull request #5 from br3ndonland/load_dotenv_multi (796e10c) + Load multiple .env files with `load_dotenv` +- Refactor `load_dotenv` into smaller methods (74ca273) +- Organize repetitive assertions with helper methods (b1c8c72) +- Add missing `from __future__ import annotations` (83b7696) +- Document how to load multiple .env files (07cfa3b) +- Load multiple .env files with `load_dotenv` (0813a5e) +- Simplify `venv` code blocks in docs (400cb3e) +- Drop "Development Status" PyPI trove classifier (a5188d1) +- Correct `find_dotenv` docstring typo (d42fd15) Tagger: Brendon Smith @@ -859,52 +859,52 @@ Special thanks to AnyIO for providing useful utilities that power this project, especially the pytest plugin and the new `anyio.Path` class released in version 3.3.0. -- Bump version from 0.0.1 to 0.1.0 (99f7e29) -- Update dependencies (f920539) -- Update to codecov-action@v2 and new uploader (046571c) -- Move CONTRIBUTING.md to docs (01ac280) -- Merge pull request #2 from br3ndonland/dotenv (ab10ad6) - Enable fastenv to manage environment variables and .env files -- Update project aims after implementing dotenv code (72c9c89) -- Use `anyio.Path` for asynchronous path operations (9eb8dc4) -- Require AnyIO (609d968) -- Remove AnyIO file I/O `# type: ignore[arg-type]` (347da2a) -- Update to `anyio@'^3.3'` (742543d) -- Add logging to `find_dotenv` and `load_dotenv` (5f28508) -- Implement async file I/O with AnyIO (9164f98) -- Implement `DotEnv` class for environment variables (512b36d) -- Add AnyIO to dependencies (efd1815) -- Add "documentation" field to pyproject.toml (ef9ba4c) -- Add "repository" field to pyproject.toml (690de61) -- Update repo tagline (dc09595) -- Improve grammar and content of comparisons docs (cebf58a) -- Use checkboxes for project aims (0df5e74) -- Clarify object storage aim in README and docs (ea00c95) -- Remove `site_url` and trailing slash from docs (5497278) -- Merge pull request #1 from br3ndonland/docs (3662c98) - Add documentation -- Add docs comparing fastenv with other projects (05836f1) -- Add placeholder for environment variable docs (940dcb5) -- Add favicon from Material for MkDocs (f6346ac) -- Update docs homepage with info from README (e669e13) -- Configure MkDocs site (02fb162) -- Create MkDocs site (69d2bd5) -- Add dependencies for docs (ea1f49c) -- Update Poetry installs for install-poetry.py (6521198) -- Run CI on Python 3.8 and 3.9 (f982106) -- Set minimum Python version to 3.8 (924c9be) -- Update dependencies (e376c5f) -- Update to Black 21.6b0 (2e45be2) -- Update dependencies (b5ad374) -- Update to mypy 0.9x (7676ef6) -- Update author info in pyproject.toml (47833fe) -- Update mypy configuration file (5472439) -- Update dependencies (2328d41) -- Update flake8 pre-commit hook for new GitHub repo (4912bfe) -- Update to Black 21.5b2 (098fdcc) -- Add classifiers and keywords to pyproject.toml (ed0b13d) -- Add PyPI badge to README (d3d54fb) -- Add Codecov badge to README (31c4b9b) +- Bump version from 0.0.1 to 0.1.0 (99f7e29) +- Update dependencies (f920539) +- Update to codecov-action@v2 and new uploader (046571c) +- Move CONTRIBUTING.md to docs (01ac280) +- Merge pull request #2 from br3ndonland/dotenv (ab10ad6) + Enable fastenv to manage environment variables and .env files +- Update project aims after implementing dotenv code (72c9c89) +- Use `anyio.Path` for asynchronous path operations (9eb8dc4) +- Require AnyIO (609d968) +- Remove AnyIO file I/O `# type: ignore[arg-type]` (347da2a) +- Update to `anyio@'^3.3'` (742543d) +- Add logging to `find_dotenv` and `load_dotenv` (5f28508) +- Implement async file I/O with AnyIO (9164f98) +- Implement `DotEnv` class for environment variables (512b36d) +- Add AnyIO to dependencies (efd1815) +- Add "documentation" field to pyproject.toml (ef9ba4c) +- Add "repository" field to pyproject.toml (690de61) +- Update repo tagline (dc09595) +- Improve grammar and content of comparisons docs (cebf58a) +- Use checkboxes for project aims (0df5e74) +- Clarify object storage aim in README and docs (ea00c95) +- Remove `site_url` and trailing slash from docs (5497278) +- Merge pull request #1 from br3ndonland/docs (3662c98) + Add documentation +- Add docs comparing fastenv with other projects (05836f1) +- Add placeholder for environment variable docs (940dcb5) +- Add favicon from Material for MkDocs (f6346ac) +- Update docs homepage with info from README (e669e13) +- Configure MkDocs site (02fb162) +- Create MkDocs site (69d2bd5) +- Add dependencies for docs (ea1f49c) +- Update Poetry installs for install-poetry.py (6521198) +- Run CI on Python 3.8 and 3.9 (f982106) +- Set minimum Python version to 3.8 (924c9be) +- Update dependencies (e376c5f) +- Update to Black 21.6b0 (2e45be2) +- Update dependencies (b5ad374) +- Update to mypy 0.9x (7676ef6) +- Update author info in pyproject.toml (47833fe) +- Update mypy configuration file (5472439) +- Update dependencies (2328d41) +- Update flake8 pre-commit hook for new GitHub repo (4912bfe) +- Update to Black 21.5b2 (098fdcc) +- Add classifiers and keywords to pyproject.toml (ed0b13d) +- Add PyPI badge to README (d3d54fb) +- Add Codecov badge to README (31c4b9b) Tagger: Brendon Smith diff --git a/docs/cloud-object-storage.md b/docs/cloud-object-storage.md index 06df5c0..2ae7c31 100644 --- a/docs/cloud-object-storage.md +++ b/docs/cloud-object-storage.md @@ -332,19 +332,19 @@ Here's an example of how this could be implemented. ### AWS S3 -- Pricing - - $23/TB/month for storage - - $90/TB/month outbound (also called download or egress), with further complex and expensive egress fees - - See the [Backblaze B2 pricing page](https://www.backblaze.com/b2/cloud-storage-pricing.html) for comparisons - - See [Backblaze Blog 2021-12-03: Why the world needs lower egress fees](https://www.backblaze.com/blog/why-the-world-needs-lower-egress-fees/) and [Cloudflare Blog 2021-07-23: AWS's egregious egress](https://blog.cloudflare.com/aws-egregious-egress/) for criticisms -- Identity and Access Management (IAM): - - [AWS IAM in S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) -- URIs: - - Path style URL: `https://s3..amazonaws.com//`. _Deprecated (see the [AWS blog](https://aws.amazon.com/blogs/aws/amazon-s3-path-deprecation-plan-the-rest-of-the-story/))_. - - [Virtual-hosted-style URL](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html): `https://.s3..amazonaws.com/`. _This is the recommended URL format_. - - S3 URI: `s3:///`. _This method is only used for certain AWS tools like the AWS CLI (see [docs](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/index.html) and [source code](https://github.com/aws/aws-cli/blob/fa4b05b4bad8574441e4d969aa1ad58a30ff550d/awscli/customizations/s3/utils.py#L217-L250))_. - - [Presigned URLs](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html) -- [Bucket naming rules](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html): +- Pricing + - $23/TB/month for storage + - $90/TB/month outbound (also called download or egress), with further complex and expensive egress fees + - See the [Backblaze B2 pricing page](https://www.backblaze.com/b2/cloud-storage-pricing.html) for comparisons + - See [Backblaze Blog 2021-12-03: Why the world needs lower egress fees](https://www.backblaze.com/blog/why-the-world-needs-lower-egress-fees/) and [Cloudflare Blog 2021-07-23: AWS's egregious egress](https://blog.cloudflare.com/aws-egregious-egress/) for criticisms +- Identity and Access Management (IAM): + - [AWS IAM in S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +- URIs: + - Path style URL: `https://s3..amazonaws.com//`. _Deprecated (see the [AWS blog](https://aws.amazon.com/blogs/aws/amazon-s3-path-deprecation-plan-the-rest-of-the-story/))_. + - [Virtual-hosted-style URL](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html): `https://.s3..amazonaws.com/`. _This is the recommended URL format_. + - S3 URI: `s3:///`. _This method is only used for certain AWS tools like the AWS CLI (see [docs](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/index.html) and [source code](https://github.com/aws/aws-cli/blob/fa4b05b4bad8574441e4d969aa1ad58a30ff550d/awscli/customizations/s3/utils.py#L217-L250))_. + - [Presigned URLs](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html) +- [Bucket naming rules](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html): > An Amazon S3 bucket name is globally unique, and the namespace is shared by all AWS accounts. This means that after a bucket is created, the name of that bucket cannot be used by another AWS account in any AWS Region until the bucket is deleted. @@ -354,98 +354,98 @@ Here's an example of how this could be implemented. ### Backblaze B2 -- [Pricing](https://www.backblaze.com/b2/cloud-storage-pricing.html): - - $6/TB/month for storage (about 1/4 the price of S3) - - Outbound (also called download or egress) data transfer fees are 1/4 the price of S3 - - See [Backblaze Blog 2021-12-03: Why the world needs lower egress fees](https://www.backblaze.com/blog/why-the-world-needs-lower-egress-fees/) -- [S3-compatible API](https://www.backblaze.com/b2/docs/s3_compatible_api.html)\* - - Downloading and listing operations are S3-compatible - - \*Uploads are different, though there are [good reasons](https://www.backblaze.com/blog/design-thinking-b2-apis-the-hidden-costs-of-s3-compatibility/) for that (helps Backblaze keep pricing low) -- URIs: - - Path style URL: `https://s3..backblazeb2.com/` - - Virtual-hosted-style URL: `https://.s3..backblazeb2.com` - - Presigned URLs are supported -- Identity and Access Management (IAM): - - Simpler than AWS, while also providing fine-grained access controls. - - No configuration of IAM users or roles needed. Access controls are configured on the access keys themselves. - - Account master access key is separate from bucket access keys - - Access key permissions can be scoped to individual buckets, and even object names within buckets. -- Docs - - [Backblaze B2 docs: Application keys](https://www.backblaze.com/b2/docs/application_keys.html) - - [Backblaze B2 docs: S3-compatible API](https://www.backblaze.com/b2/docs/s3_compatible_api.html) +- [Pricing](https://www.backblaze.com/b2/cloud-storage-pricing.html): + - $6/TB/month for storage (about 1/4 the price of S3) + - Outbound (also called download or egress) data transfer fees are 1/4 the price of S3 + - See [Backblaze Blog 2021-12-03: Why the world needs lower egress fees](https://www.backblaze.com/blog/why-the-world-needs-lower-egress-fees/) +- [S3-compatible API](https://www.backblaze.com/b2/docs/s3_compatible_api.html)\* + - Downloading and listing operations are S3-compatible + - \*Uploads are different, though there are [good reasons](https://www.backblaze.com/blog/design-thinking-b2-apis-the-hidden-costs-of-s3-compatibility/) for that (helps Backblaze keep pricing low) +- URIs: + - Path style URL: `https://s3..backblazeb2.com/` + - Virtual-hosted-style URL: `https://.s3..backblazeb2.com` + - Presigned URLs are supported +- Identity and Access Management (IAM): + - Simpler than AWS, while also providing fine-grained access controls. + - No configuration of IAM users or roles needed. Access controls are configured on the access keys themselves. + - Account master access key is separate from bucket access keys + - Access key permissions can be scoped to individual buckets, and even object names within buckets. +- Docs + - [Backblaze B2 docs: Application keys](https://www.backblaze.com/b2/docs/application_keys.html) + - [Backblaze B2 docs: S3-compatible API](https://www.backblaze.com/b2/docs/s3_compatible_api.html) ### Cloudflare R2 -- [Pricing](https://developers.cloudflare.com/r2/platform/pricing/) - - $15/TB/month for storage (about half the price of AWS S3, but over double the price of Backblaze B2) -- [S3-compatible API](https://developers.cloudflare.com/r2/platform/s3-compatibility/api/) -- URIs - - Regions are handled automatically. "When using the S3 API, the region for an R2 bucket is `auto`. For compatibility with tools that do not allow you to specify a region, an empty value and `us-east-1` will alias to the `auto` region." - - Cloudflare R2 URLs are different from other S3-compatible object storage platforms. The Cloudflare account ID is included in bucket URIs, but the region is not. - - Path style URL: `https://.r2.cloudflarestorage.com/` - - Virtual-hosted-style URL: `https://..r2.cloudflarestorage.com` (added [2022-05-16](https://developers.cloudflare.com/r2/platform/changelog/#2022-05-16), also see [cloudflare/cloudflare-docs#6405](https://github.com/cloudflare/cloudflare-docs/pull/6405)), though note that the docs on [using the AWS CLI with R2](https://developers.cloudflare.com/r2/examples/aws/aws-cli/) and and [using Boto3 with R2](https://developers.cloudflare.com/r2/examples/aws/boto3/) still show only path style URLs. - - Presigned URLs are supported - - Added [2022-06-17](https://developers.cloudflare.com/r2/platform/changelog/#2022-06-17) - - There may be CORS limitations on uploads due to lack of ability to set the `Access-Control-Allow-Origin` header ([cloudflare/cloudflare-docs#4455](https://github.com/cloudflare/cloudflare-docs/issues/4455)). - - [Presigned `POST` is not currently supported](https://developers.cloudflare.com/r2/api/s3/presigned-urls/#supported-http-methods). -- Identity and Access Management (IAM): - - [Requires generation of a static access key](https://developers.cloudflare.com/r2/data-access/s3-api/tokens/). Does not appear to support temporary credentials from IAM roles (AWS session tokens). Does not appear to support OpenID Connect (OIDC). - - Access keys can be set to either read-only or edit permissions. - - Access keys can be scoped to specific Cloudflare products, Cloudflare accounts, and IP addresses. -- Lifecycle policies - - Added [2023-03-16](https://developers.cloudflare.com/r2/reference/changelog/#2023-03-16) ([blog post](https://blog.cloudflare.com/introducing-object-lifecycle-management-for-cloudflare-r2/)) - - [Docs](https://developers.cloudflare.com/r2/buckets/object-lifecycles/) -- Docs - - [Cloudflare R2 docs](https://developers.cloudflare.com/r2/) - - [Cloudflare Blog 2021-07-23: AWS's egregious egress](https://blog.cloudflare.com/aws-egregious-egress/) - - [Cloudflare Blog 2021-09-28: Announcing Cloudflare R2 Storage](https://blog.cloudflare.com/introducing-r2-object-storage/) - - [Cloudflare Blog 2022-09-21: R2 is now Generally Available](https://blog.cloudflare.com/r2-ga/) +- [Pricing](https://developers.cloudflare.com/r2/platform/pricing/) + - $15/TB/month for storage (about half the price of AWS S3, but over double the price of Backblaze B2) +- [S3-compatible API](https://developers.cloudflare.com/r2/platform/s3-compatibility/api/) +- URIs + - Regions are handled automatically. "When using the S3 API, the region for an R2 bucket is `auto`. For compatibility with tools that do not allow you to specify a region, an empty value and `us-east-1` will alias to the `auto` region." + - Cloudflare R2 URLs are different from other S3-compatible object storage platforms. The Cloudflare account ID is included in bucket URIs, but the region is not. + - Path style URL: `https://.r2.cloudflarestorage.com/` + - Virtual-hosted-style URL: `https://..r2.cloudflarestorage.com` (added [2022-05-16](https://developers.cloudflare.com/r2/platform/changelog/#2022-05-16), also see [cloudflare/cloudflare-docs#6405](https://github.com/cloudflare/cloudflare-docs/pull/6405)), though note that the docs on [using the AWS CLI with R2](https://developers.cloudflare.com/r2/examples/aws/aws-cli/) and and [using Boto3 with R2](https://developers.cloudflare.com/r2/examples/aws/boto3/) still show only path style URLs. + - Presigned URLs are supported + - Added [2022-06-17](https://developers.cloudflare.com/r2/platform/changelog/#2022-06-17) + - There may be CORS limitations on uploads due to lack of ability to set the `Access-Control-Allow-Origin` header ([cloudflare/cloudflare-docs#4455](https://github.com/cloudflare/cloudflare-docs/issues/4455)). + - [Presigned `POST` is not currently supported](https://developers.cloudflare.com/r2/api/s3/presigned-urls/#supported-http-methods). +- Identity and Access Management (IAM): + - [Requires generation of a static access key](https://developers.cloudflare.com/r2/data-access/s3-api/tokens/). Does not appear to support temporary credentials from IAM roles (AWS session tokens). Does not appear to support OpenID Connect (OIDC). + - Access keys can be set to either read-only or edit permissions. + - Access keys can be scoped to specific Cloudflare products, Cloudflare accounts, and IP addresses. +- Lifecycle policies + - Added [2023-03-16](https://developers.cloudflare.com/r2/reference/changelog/#2023-03-16) ([blog post](https://blog.cloudflare.com/introducing-object-lifecycle-management-for-cloudflare-r2/)) + - [Docs](https://developers.cloudflare.com/r2/buckets/object-lifecycles/) +- Docs + - [Cloudflare R2 docs](https://developers.cloudflare.com/r2/) + - [Cloudflare Blog 2021-07-23: AWS's egregious egress](https://blog.cloudflare.com/aws-egregious-egress/) + - [Cloudflare Blog 2021-09-28: Announcing Cloudflare R2 Storage](https://blog.cloudflare.com/introducing-r2-object-storage/) + - [Cloudflare Blog 2022-09-21: R2 is now Generally Available](https://blog.cloudflare.com/r2-ga/) ### DigitalOcean Spaces -- Pricing: $5 monthly flat rate - - Up to 250GB of data storage - - No charge for inbound data transfer - - Up to 1TB of outbound data transfer (also called download or egress) -- [S3-compatible API](https://docs.digitalocean.com/reference/api/spaces-api/) -- URIs: - - Path style URL: `https://.digitaloceanspaces.com/` - - Virtual-hosted-style URL: `https://..digitaloceanspaces.com` - - Presigned URLs are supported -- Identity and Access Management (IAM): - - Minimal (access keys automatically access all buckets/"spaces") - - Access keys can be created without paying the monthly fee -- Docs - - [DigitalOcean docs: Spaces](https://docs.digitalocean.com/products/spaces/) - - [DigitalOcean docs: Spaces - Using DigitalOcean Spaces with AWS S3 SDKs](https://docs.digitalocean.com/products/spaces/resources/s3-sdk-examples/) - - [DigitalOcean docs: Spaces - How-Tos - Manage access to Spaces](https://docs.digitalocean.com/products/spaces/how-to/manage-access/) +- Pricing: $5 monthly flat rate + - Up to 250GB of data storage + - No charge for inbound data transfer + - Up to 1TB of outbound data transfer (also called download or egress) +- [S3-compatible API](https://docs.digitalocean.com/reference/api/spaces-api/) +- URIs: + - Path style URL: `https://.digitaloceanspaces.com/` + - Virtual-hosted-style URL: `https://..digitaloceanspaces.com` + - Presigned URLs are supported +- Identity and Access Management (IAM): + - Minimal (access keys automatically access all buckets/"spaces") + - Access keys can be created without paying the monthly fee +- Docs + - [DigitalOcean docs: Spaces](https://docs.digitalocean.com/products/spaces/) + - [DigitalOcean docs: Spaces - Using DigitalOcean Spaces with AWS S3 SDKs](https://docs.digitalocean.com/products/spaces/resources/s3-sdk-examples/) + - [DigitalOcean docs: Spaces - How-Tos - Manage access to Spaces](https://docs.digitalocean.com/products/spaces/how-to/manage-access/) ### Google Cloud Storage -- [Pricing](https://cloud.google.com/storage/pricing) (see the [Backblaze B2 pricing page](https://www.backblaze.com/b2/cloud-storage-pricing.html) for comparisons) -- [S3-compatible API? Mostly?](https://cloud.google.com/storage/docs/migrating) -- URIs: - - Path style URL: `https://storage.googleapis.com/storage/v1/b//o/` - - Virtual-hosted-style URLs? - - [Presigned URLs are supported](https://cloud.google.com/storage/docs/access-control/signed-urls) -- [Identity and Access Management (IAM)](https://cloud.google.com/storage/docs/access-control/iam) -- [Docs](https://cloud.google.com/storage/docs) +- [Pricing](https://cloud.google.com/storage/pricing) (see the [Backblaze B2 pricing page](https://www.backblaze.com/b2/cloud-storage-pricing.html) for comparisons) +- [S3-compatible API? Mostly?](https://cloud.google.com/storage/docs/migrating) +- URIs: + - Path style URL: `https://storage.googleapis.com/storage/v1/b//o/` + - Virtual-hosted-style URLs? + - [Presigned URLs are supported](https://cloud.google.com/storage/docs/access-control/signed-urls) +- [Identity and Access Management (IAM)](https://cloud.google.com/storage/docs/access-control/iam) +- [Docs](https://cloud.google.com/storage/docs) ### Linode Object Storage -- Pricing: $5 monthly flat rate (same as DigitalOcean Spaces) - - 250GB of data storage included in the flat rate - - No charge for inbound data transfer - - Up to 1TB of outbound data transfer (also called download or egress) - - Up to 50 Million objects per cluster -- S3-compatible API -- URIs: - - Path style URL: `https://.linodeobjects.com/` - - Virtual-hosted-style URL: `https://..linodeobjects.com` - - Presigned URLs are supported -- Identity and Access Management (IAM): - - Minimal (access keys automatically access all buckets) - - Access keys cannot be created without paying the monthly fee first -- Docs - - [Linode docs: Storage - Object Storage - Overview](https://www.linode.com/docs/products/storage/object-storage/) - - [Linode docs: Storage - Object Storage - Guides - Using the AWS SDK for Python (boto3) with Object Storage](https://www.linode.com/docs/products/storage/object-storage/guides/aws-sdk-for-python/) +- Pricing: $5 monthly flat rate (same as DigitalOcean Spaces) + - 250GB of data storage included in the flat rate + - No charge for inbound data transfer + - Up to 1TB of outbound data transfer (also called download or egress) + - Up to 50 Million objects per cluster +- S3-compatible API +- URIs: + - Path style URL: `https://.linodeobjects.com/` + - Virtual-hosted-style URL: `https://..linodeobjects.com` + - Presigned URLs are supported +- Identity and Access Management (IAM): + - Minimal (access keys automatically access all buckets) + - Access keys cannot be created without paying the monthly fee first +- Docs + - [Linode docs: Storage - Object Storage - Overview](https://www.linode.com/docs/products/storage/object-storage/) + - [Linode docs: Storage - Object Storage - Guides - Using the AWS SDK for Python (boto3) with Object Storage](https://www.linode.com/docs/products/storage/object-storage/guides/aws-sdk-for-python/) diff --git a/docs/comparisons.md b/docs/comparisons.md index aab8bdf..31067ae 100644 --- a/docs/comparisons.md +++ b/docs/comparisons.md @@ -18,10 +18,10 @@ See the [`os` module docs](https://docs.python.org/3/library/os.html) and the [d ## environs -- [environs](https://github.com/sloria/environs) is a project with useful features for managing _.env_ files and application settings. Its API was inspired by [django-environ](https://github.com/joke2k/django-environ) and [envparse](https://github.com/rconradharris/envparse) (and the maintainers [considered](https://github.com/rconradharris/envparse/issues/12) merging environs and envparse into one project). The _README_ [compares](https://github.com/sloria/environs#why) environs to `os.environ`, and justifies the additional features that environs provides. -- While it _separates_ config from code, as suggested by the [twelve-factor app](https://12factor.net/config) methodology, it also _combines_ environment variables and settings. Environment variables and their type-casted setting counterparts are combined into the same model. -- Initially, the source code wasn't consistently type-annotated ([sloria/environs#186](https://github.com/sloria/environs/issues/186)), but based on its [PEP 561](https://www.python.org/dev/peps/pep-0561/) marker file, it appears to be type-annotated now. -- Depends on python-dotenv ([sloria/environs#196](https://github.com/sloria/environs/issues/196)), so it inherits the limitations described in the [python-dotenv section](#python-dotenv). +- [environs](https://github.com/sloria/environs) is a project with useful features for managing _.env_ files and application settings. Its API was inspired by [django-environ](https://github.com/joke2k/django-environ) and [envparse](https://github.com/rconradharris/envparse) (and the maintainers [considered](https://github.com/rconradharris/envparse/issues/12) merging environs and envparse into one project). The _README_ [compares](https://github.com/sloria/environs#why) environs to `os.environ`, and justifies the additional features that environs provides. +- While it _separates_ config from code, as suggested by the [twelve-factor app](https://12factor.net/config) methodology, it also _combines_ environment variables and settings. Environment variables and their type-casted setting counterparts are combined into the same model. +- Initially, the source code wasn't consistently type-annotated ([sloria/environs#186](https://github.com/sloria/environs/issues/186)), but based on its [PEP 561](https://www.python.org/dev/peps/pep-0561/) marker file, it appears to be type-annotated now. +- Depends on python-dotenv ([sloria/environs#196](https://github.com/sloria/environs/issues/196)), so it inherits the limitations described in the [python-dotenv section](#python-dotenv). ## _pydantic_ @@ -54,16 +54,16 @@ _pydantic_ offers a [`BaseSettings` model](https://pydantic-docs.helpmanual.io/u ### File I/O -- In addition to reading environment variables that have already been set, _pydantic_ can load environment variables from _.env_ files. However, it depends on python-dotenv to load _.env_ files, so it inherits the limitations described in the [python-dotenv section](#python-dotenv). -- If no _.env_ file is found at the path provided, _pydantic_ will fail silently, rather than raising a `FileNotFoundError`. This can lead to issues if applications depend on environment variables that _pydantic_ fails to load. +- In addition to reading environment variables that have already been set, _pydantic_ can load environment variables from _.env_ files. However, it depends on python-dotenv to load _.env_ files, so it inherits the limitations described in the [python-dotenv section](#python-dotenv). +- If no _.env_ file is found at the path provided, _pydantic_ will fail silently, rather than raising a `FileNotFoundError`. This can lead to issues if applications depend on environment variables that _pydantic_ fails to load. ## python-decouple -- [python-decouple](https://github.com/henriquebastos/python-decouple) loads settings from _.env_ and _.ini_ files. Its supported configuration file format appears to be inspired by [Foreman](https://github.com/ddollar/foreman), a Ruby configuration management tool. -- Variables are set with calls to instances of its `AutoConfig` class, which offers type-casting to convert strings to other Python types: `config("DEBUG", cast=bool)`. -- Source code is not type-annotated. -- Classes inherit from `object`, and therefore require their own implementations of methods already present in other data structures. This could be easily eliminated by inheriting from a mapping data structure such as `collections.abc.MutableMapping`. -- Continues supporting Python 2 after its [end-of-life](https://www.python.org/doc/sunset-python-2/), and has not been tested on the latest versions of Python 3. +- [python-decouple](https://github.com/henriquebastos/python-decouple) loads settings from _.env_ and _.ini_ files. Its supported configuration file format appears to be inspired by [Foreman](https://github.com/ddollar/foreman), a Ruby configuration management tool. +- Variables are set with calls to instances of its `AutoConfig` class, which offers type-casting to convert strings to other Python types: `config("DEBUG", cast=bool)`. +- Source code is not type-annotated. +- Classes inherit from `object`, and therefore require their own implementations of methods already present in other data structures. This could be easily eliminated by inheriting from a mapping data structure such as `collections.abc.MutableMapping`. +- Continues supporting Python 2 after its [end-of-life](https://www.python.org/doc/sunset-python-2/), and has not been tested on the latest versions of Python 3. ## python-dotenv @@ -71,52 +71,52 @@ _pydantic_ offers a [`BaseSettings` model](https://pydantic-docs.helpmanual.io/u ### Environment variables -- Its primary data structure, `dotenv.main.DotEnv`, inherits from `object`. As a result, it requires its own mapping methods (such as `dict()`) that could be obviated by inheriting from a mapping data structure such as `collections.abc.MutableMapping`. -- Other methods have confusing, counter-intuitive APIs. For example, the `load_dotenv()` function is supposed to "Parse a .env file and then load all the variables found as environment variables," according to its docstring. However, the function always returns `True`, even if no _.env_ file is found or no environment variables are set, because of `DotEnv.set_as_environment_variables()`. Furthermore, this confusing behavior is not documented, because, as the maintainer [commented](https://github.com/theskumar/python-dotenv/issues/164#issuecomment-494750043), "The return value of `load_dotenv` is undocumented as I was planning to do something useful with it, but could not settle down to one." +- Its primary data structure, `dotenv.main.DotEnv`, inherits from `object`. As a result, it requires its own mapping methods (such as `dict()`) that could be obviated by inheriting from a mapping data structure such as `collections.abc.MutableMapping`. +- Other methods have confusing, counter-intuitive APIs. For example, the `load_dotenv()` function is supposed to "Parse a .env file and then load all the variables found as environment variables," according to its docstring. However, the function always returns `True`, even if no _.env_ file is found or no environment variables are set, because of `DotEnv.set_as_environment_variables()`. Furthermore, this confusing behavior is not documented, because, as the maintainer [commented](https://github.com/theskumar/python-dotenv/issues/164#issuecomment-494750043), "The return value of `load_dotenv` is undocumented as I was planning to do something useful with it, but could not settle down to one." ### File I/O -- Loads files with the synchronous `open()` built-in function. Async support is not provided. -- Does not integrate with object storage like AWS S3. +- Loads files with the synchronous `open()` built-in function. Async support is not provided. +- Does not integrate with object storage like AWS S3. ### Project maintenance -- Continued supporting Python 2 after its [end-of-life](https://www.python.org/doc/sunset-python-2/) (until 0.19.0), so it had to use [Python 2 type comments](https://mypy.readthedocs.io/en/stable/python2.html) and other legacy cruft. -- Maintainers have not been receptive to improvements (see [theskumar/python-dotenv#263](https://github.com/theskumar/python-dotenv/pull/263) for context). +- Continued supporting Python 2 after its [end-of-life](https://www.python.org/doc/sunset-python-2/) (until 0.19.0), so it had to use [Python 2 type comments](https://mypy.readthedocs.io/en/stable/python2.html) and other legacy cruft. +- Maintainers have not been receptive to improvements (see [theskumar/python-dotenv#263](https://github.com/theskumar/python-dotenv/pull/263) for context). ### Comparing fastenv and python-dotenv #### `DotEnv` -- Both fastenv and python-dotenv provide a `DotEnv` class for managing environment variables -- `fastenv.DotEnv` inherits from `collections.abc.MutableMapping`, `dotenv.main.DotEnv` inherits from `object` -- fastenv includes `DotEnv` in its `__all__`, python-dotenv does not (it must be directly imported from `dotenv.main`) +- Both fastenv and python-dotenv provide a `DotEnv` class for managing environment variables +- `fastenv.DotEnv` inherits from `collections.abc.MutableMapping`, `dotenv.main.DotEnv` inherits from `object` +- fastenv includes `DotEnv` in its `__all__`, python-dotenv does not (it must be directly imported from `dotenv.main`) #### `find_dotenv` -- fastenv: `await fastenv.find_dotenv()` (async) -- python-dotenv: `dotenv.find_dotenv()` (sync) -- Both fastenv and python-dotenv look for `".env"` by default -- Both python-dotenv and fastenv return `os.PathLike` objects -- fastenv raises `FileNotFoundError` exceptions by default if files are not found, python-dotenv does not +- fastenv: `await fastenv.find_dotenv()` (async) +- python-dotenv: `dotenv.find_dotenv()` (sync) +- Both fastenv and python-dotenv look for `".env"` by default +- Both python-dotenv and fastenv return `os.PathLike` objects +- fastenv raises `FileNotFoundError` exceptions by default if files are not found, python-dotenv does not #### `load_dotenv` -- fastenv: `await fastenv.load_dotenv()` (async) -- python-dotenv: `dotenv.load_dotenv()` (sync) -- `fastenv.load_dotenv` can load multiple _.env_ files in a single call, `dotenv.load_dotenv` cannot -- `fastenv.load_dotenv` logs the number of environment variables loaded, `dotenv.load_dotenv` does not -- `fastenv.load_dotenv` returns a `DotEnv` model, `dotenv.load_dotenv` returns `True` (even if no _.env_ file was found and no environment variables were loaded) +- fastenv: `await fastenv.load_dotenv()` (async) +- python-dotenv: `dotenv.load_dotenv()` (sync) +- `fastenv.load_dotenv` can load multiple _.env_ files in a single call, `dotenv.load_dotenv` cannot +- `fastenv.load_dotenv` logs the number of environment variables loaded, `dotenv.load_dotenv` does not +- `fastenv.load_dotenv` returns a `DotEnv` model, `dotenv.load_dotenv` returns `True` (even if no _.env_ file was found and no environment variables were loaded) #### `find_dotenv` with `load_dotenv` Users who would like to ensure their _.env_ files are found, and log the result, should be aware that `dotenv.load_dotenv`: -- Only calls `find_dotenv` if a file path is not provided, and does not pass an argument through to `find_dotenv` to raise exceptions if the file is not found -- Requires a call to `DotEnv.set_as_environment_variables` to actually set environment variables -- Does not provide logging -- Does not provide exception handling (its `verbose` argument does not necessarily raise an exception) -- Does not return the `DotEnv` instance created by `load_dotenv`, but always returns `True`, even if no _.env_ file is found or no environment variables are set +- Only calls `find_dotenv` if a file path is not provided, and does not pass an argument through to `find_dotenv` to raise exceptions if the file is not found +- Requires a call to `DotEnv.set_as_environment_variables` to actually set environment variables +- Does not provide logging +- Does not provide exception handling (its `verbose` argument does not necessarily raise an exception) +- Does not return the `DotEnv` instance created by `load_dotenv`, but always returns `True`, even if no _.env_ file is found or no environment variables are set Something like the following is therefore needed instead of using `dotenv.load_dotenv`: @@ -146,24 +146,24 @@ Something like the following is therefore needed instead of using `dotenv.load_d The above effect can be accomplished with fastenv in a single call, `await fastenv.load_dotenv(find_source=True)`. This call to `fastenv.load_dotenv`: -- Finds the _.env_ file (`find_source=True`) with its `find_dotenv` method and the file name provided (`".env"` by default), logging and raising a `FileNotFoundError` if not found -- Sets environment variables automatically -- Logs successes and errors automatically -- Raises exceptions by default -- Returns a `DotEnv` instance +- Finds the _.env_ file (`find_source=True`) with its `find_dotenv` method and the file name provided (`".env"` by default), logging and raising a `FileNotFoundError` if not found +- Sets environment variables automatically +- Logs successes and errors automatically +- Raises exceptions by default +- Returns a `DotEnv` instance #### `dotenv_values` -- fastenv: `await fastenv.dotenv_values()` (async) -- python-dotenv: `dotenv.dotenv_values()` (sync) -- `fastenv.dotenv_values` offers a `find_dotenv` argument to find files before loading and returning values, `dotenv.dotenv_values` does not -- `fastenv.dotenv_values` offers a `raise_exceptions` argument to determine whether or not exceptions will be raised, `dotenv.dotenv_values` does not (its `verbose` argument does not necessarily raise an exception) -- `fastenv.dotenv_values` logs successes and errors automatically, `dotenv.dotenv_values` does not +- fastenv: `await fastenv.dotenv_values()` (async) +- python-dotenv: `dotenv.dotenv_values()` (sync) +- `fastenv.dotenv_values` offers a `find_dotenv` argument to find files before loading and returning values, `dotenv.dotenv_values` does not +- `fastenv.dotenv_values` offers a `raise_exceptions` argument to determine whether or not exceptions will be raised, `dotenv.dotenv_values` does not (its `verbose` argument does not necessarily raise an exception) +- `fastenv.dotenv_values` logs successes and errors automatically, `dotenv.dotenv_values` does not #### Writing to _.env_ files -- fastenv: `await fastenv.dump_dotenv()` (async, and writes an entire `DotEnv` model to a file) -- python-dotenv: `dotenv.get_key()`, `dotenv.set_key()`, `dotenv.unset_key()` (sync, and can only write single variables to a file) +- fastenv: `await fastenv.dump_dotenv()` (async, and writes an entire `DotEnv` model to a file) +- python-dotenv: `dotenv.get_key()`, `dotenv.set_key()`, `dotenv.unset_key()` (sync, and can only write single variables to a file) ## Starlette @@ -246,9 +246,9 @@ It is also important to note that the one-way preference will only be enforced w ### File I/O -- Starlette `Config` accepts an `env_file` keyword argument, which should point to a _.env_ file on disk. It loads the file with the synchronous `open()` built-in function. -- If no _.env_ file is found at the path provided by `Config(env_file)`, Starlette will raise a warning instead of a `FileNotFoundError` ([encode/starlette#2422](https://github.com/encode/starlette/pull/2422), [encode/starlette#2446](https://github.com/encode/starlette/discussions/2446), [encode/starlette#2485](https://github.com/encode/starlette/pull/2485)). This can lead to issues if applications depend on environment variables that Starlette fails to load. -- Starlette `Config` does not support multiple _.env_ files ([encode/starlette#432](https://github.com/encode/starlette/issues/432)). +- Starlette `Config` accepts an `env_file` keyword argument, which should point to a _.env_ file on disk. It loads the file with the synchronous `open()` built-in function. +- If no _.env_ file is found at the path provided by `Config(env_file)`, Starlette will raise a warning instead of a `FileNotFoundError` ([encode/starlette#2422](https://github.com/encode/starlette/pull/2422), [encode/starlette#2446](https://github.com/encode/starlette/discussions/2446), [encode/starlette#2485](https://github.com/encode/starlette/pull/2485)). This can lead to issues if applications depend on environment variables that Starlette fails to load. +- Starlette `Config` does not support multiple _.env_ files ([encode/starlette#432](https://github.com/encode/starlette/issues/432)). ### The future of `starlette.config` @@ -264,7 +264,7 @@ From [encode/starlette#432](https://github.com/encode/starlette/issues/432#issue ## Other -- [dotenvy](https://github.com/chickenzord/dotenvy) can load _.env_ files and apply a type schema to the variables. It does not appear to be actively maintained. -- [env](https://github.com/MasterOdin/env) does not add much beyond `os.environ` (does not even load files), has not been released since 2012, and does not appear to be actively maintained. -- [envparse](https://github.com/rconradharris/envparse) offers features for parsing and type-casting environment variables, but does not appear to be actively maintained. -- [python-configurator](https://github.com/guitarpoet/python-configurator) depends on python-dotenv and appears to emphasize TOML settings files. +- [dotenvy](https://github.com/chickenzord/dotenvy) can load _.env_ files and apply a type schema to the variables. It does not appear to be actively maintained. +- [env](https://github.com/MasterOdin/env) does not add much beyond `os.environ` (does not even load files), has not been released since 2012, and does not appear to be actively maintained. +- [envparse](https://github.com/rconradharris/envparse) offers features for parsing and type-casting environment variables, but does not appear to be actively maintained. +- [python-configurator](https://github.com/guitarpoet/python-configurator) depends on python-dotenv and appears to emphasize TOML settings files. diff --git a/docs/contributing.md b/docs/contributing.md index 6e8c82d..5c24021 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -4,20 +4,20 @@ **PRs welcome!** -- **Consider starting a [discussion](https://github.com/br3ndonland/fastenv/discussions) to see if there's interest in what you want to do.** -- **Submit PRs from feature branches on forks to the `develop` branch.** -- **Ensure PRs pass all CI checks.** -- **Maintain test coverage at 100%.** +- **Consider starting a [discussion](https://github.com/br3ndonland/fastenv/discussions) to see if there's interest in what you want to do.** +- **Submit PRs from feature branches on forks to the `develop` branch.** +- **Ensure PRs pass all CI checks.** +- **Maintain test coverage at 100%.** ## Git -- _[Why use Git?](https://www.git-scm.com/about)_ Git enables creation of multiple versions of a code repository called branches, with the ability to track and undo changes in detail. -- Install Git by [downloading](https://www.git-scm.com/downloads) from the website, or with a package manager like [Homebrew](https://brew.sh/). -- [Configure Git to connect to GitHub with SSH](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh). -- [Fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) this repo. -- Create a [branch](https://www.git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell) in your fork. -- Commit your changes with a [properly-formatted Git commit message](https://chris.beams.io/posts/git-commit/). -- Create a [pull request (PR)](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests) to incorporate your changes into the upstream project you forked. +- _[Why use Git?](https://www.git-scm.com/about)_ Git enables creation of multiple versions of a code repository called branches, with the ability to track and undo changes in detail. +- Install Git by [downloading](https://www.git-scm.com/downloads) from the website, or with a package manager like [Homebrew](https://brew.sh/). +- [Configure Git to connect to GitHub with SSH](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh). +- [Fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) this repo. +- Create a [branch](https://www.git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell) in your fork. +- Commit your changes with a [properly-formatted Git commit message](https://chris.beams.io/posts/git-commit/). +- Create a [pull request (PR)](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests) to incorporate your changes into the upstream project you forked. ## Python @@ -27,10 +27,10 @@ This project uses [Hatch](https://hatch.pypa.io/latest/) for dependency manageme #### Highlights -- **Automatic virtual environment management**: [Hatch automatically manages the application environment](https://hatch.pypa.io/latest/environment/). -- **Dependency resolution**: Hatch will automatically resolve any dependency version conflicts using the [`pip` dependency resolver](https://pip.pypa.io/en/stable/topics/dependency-resolution/). -- **Dependency separation**: [Hatch supports separate lists of optional dependencies in the _pyproject.toml_](https://hatch.pypa.io/latest/config/dependency/). Production installs can skip optional dependencies for speed. -- **Builds**: [Hatch has features for easily building the project into a Python package](https://hatch.pypa.io/latest/build/) and [publishing the package to PyPI](https://hatch.pypa.io/latest/publish/). +- **Automatic virtual environment management**: [Hatch automatically manages the application environment](https://hatch.pypa.io/latest/environment/). +- **Dependency resolution**: Hatch will automatically resolve any dependency version conflicts using the [`pip` dependency resolver](https://pip.pypa.io/en/stable/topics/dependency-resolution/). +- **Dependency separation**: [Hatch supports separate lists of optional dependencies in the _pyproject.toml_](https://hatch.pypa.io/latest/config/dependency/). Production installs can skip optional dependencies for speed. +- **Builds**: [Hatch has features for easily building the project into a Python package](https://hatch.pypa.io/latest/build/) and [publishing the package to PyPI](https://hatch.pypa.io/latest/publish/). #### Installation @@ -55,18 +55,18 @@ export HATCH_ENV_TYPE_VIRTUAL_PATH=.venv # install virtualenvs into .venv #### General info -- Tests are in the _tests/_ directory. -- Run tests by [invoking `pytest` from the command-line](https://docs.pytest.org/en/latest/how-to/usage.html) within the virtual environment in the root directory of the repo. -- [pytest](https://docs.pytest.org/en/latest/) features used include: - - [capturing `stdout` with `capfd`](https://docs.pytest.org/en/latest/how-to/capture-stdout-stderr.html) - - [fixtures](https://docs.pytest.org/en/latest/how-to/fixtures.html) - - [monkeypatch](https://docs.pytest.org/en/latest/how-to/monkeypatch.html) - - [parametrize](https://docs.pytest.org/en/latest/how-to/parametrize.html) - - [temporary directories and files (`tmp_path` and `tmp_dir`)](https://docs.pytest.org/en/latest/how-to/tmpdir.html) -- [pytest plugins](https://docs.pytest.org/en/latest/how-to/plugins.html) include: - - [pytest-mock](https://github.com/pytest-dev/pytest-mock) -- [pytest configuration](https://docs.pytest.org/en/latest/reference/customize.html) is in _[pyproject.toml](https://github.com/br3ndonland/fastenv/blob/develop/pyproject.toml)_. -- Test coverage reports are generated by [coverage.py](https://github.com/nedbat/coveragepy). To generate test coverage reports, first run tests with `coverage run`, then generate a report with `coverage report`. To see interactive HTML coverage reports, run `coverage html` instead of `coverage report`. +- Tests are in the _tests/_ directory. +- Run tests by [invoking `pytest` from the command-line](https://docs.pytest.org/en/latest/how-to/usage.html) within the virtual environment in the root directory of the repo. +- [pytest](https://docs.pytest.org/en/latest/) features used include: + - [capturing `stdout` with `capfd`](https://docs.pytest.org/en/latest/how-to/capture-stdout-stderr.html) + - [fixtures](https://docs.pytest.org/en/latest/how-to/fixtures.html) + - [monkeypatch](https://docs.pytest.org/en/latest/how-to/monkeypatch.html) + - [parametrize](https://docs.pytest.org/en/latest/how-to/parametrize.html) + - [temporary directories and files (`tmp_path` and `tmp_dir`)](https://docs.pytest.org/en/latest/how-to/tmpdir.html) +- [pytest plugins](https://docs.pytest.org/en/latest/how-to/plugins.html) include: + - [pytest-mock](https://github.com/pytest-dev/pytest-mock) +- [pytest configuration](https://docs.pytest.org/en/latest/reference/customize.html) is in _[pyproject.toml](https://github.com/br3ndonland/fastenv/blob/develop/pyproject.toml)_. +- Test coverage reports are generated by [coverage.py](https://github.com/nedbat/coveragepy). To generate test coverage reports, first run tests with `coverage run`, then generate a report with `coverage report`. To see interactive HTML coverage reports, run `coverage html` instead of `coverage report`. #### Integration testing instructions @@ -74,8 +74,8 @@ Integration tests will be skipped if cloud credentials are not present. Running ##### Make buckets on each supported cloud platform -- [AWS S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/creating-bucket.html) -- [Backblaze B2](https://help.backblaze.com/hc/en-us/articles/1260803542610-Creating-a-B2-Bucket-using-the-Web-UI) +- [AWS S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/creating-bucket.html) +- [Backblaze B2](https://help.backblaze.com/hc/en-us/articles/1260803542610-Creating-a-B2-Bucket-using-the-Web-UI) ##### Upload objects to each bucket @@ -207,22 +207,22 @@ AWS_IAM_ACCESS_KEY_FASTENV=$(aws configure get fastenv.aws_access_key_id) \ Code quality checks can be run using the Hatch scripts in _pyproject.toml_. -- Check: `hatch run check` -- Format: `hatch run format` +- Check: `hatch run check` +- Format: `hatch run format` ### Code style -- Python code is formatted with [Ruff](https://docs.astral.sh/ruff/). Ruff configuration is stored in _pyproject.toml_. -- Other web code (JSON, Markdown, YAML) is formatted with [Prettier](https://prettier.io/). +- Python code is formatted with [Ruff](https://docs.astral.sh/ruff/). Ruff configuration is stored in _pyproject.toml_. +- Other web code (JSON, Markdown, YAML) is formatted with [Prettier](https://prettier.io/). ### Static type checking -- To learn type annotation basics, see the [Python typing module docs](https://docs.python.org/3/library/typing.html), [Python type annotations how-to](https://docs.python.org/3/howto/annotations.html), the [Real Python type checking tutorial](https://realpython.com/python-type-checking/), and [this gist](https://gist.github.com/987bdc6263217895d4bf03d0a5ff114c). -- Type annotations are not used at runtime. The standard library `typing` module includes a `TYPE_CHECKING` constant that is `False` at runtime, but `True` when conducting static type checking prior to runtime. Type imports are included under `if TYPE_CHECKING:` conditions so that they are not imported at runtime. These conditions are ignored when calculating test coverage. -- Type annotations can be provided inline or in separate stub files. Much of the Python standard library is annotated with stubs. For example, the Python standard library [`logging.config` module uses type stubs](https://github.com/python/typeshed/blob/main/stdlib/logging/config.pyi). The typeshed types for the `logging.config` module are used solely for type-checking usage of the `logging.config` module itself. They cannot be imported and used to type annotate other modules. -- The standard library `typing` module includes a `NoReturn` type. This would seem useful for [unreachable code](https://typing.readthedocs.io/en/stable/source/unreachable.html), including functions that do not return a value, such as test functions. Unfortunately mypy reports an error when using `NoReturn`, "Implicit return in function which does not return (misc)." To avoid headaches from the opaque "misc" category of [mypy errors](https://mypy.readthedocs.io/en/stable/error_code_list.html), these functions are annotated as returning `None`. -- [Mypy](https://mypy.readthedocs.io/en/stable/) is used for type-checking. [Mypy configuration](https://mypy.readthedocs.io/en/stable/config_file.html) is included in _pyproject.toml_. -- Mypy strict mode is enabled. Strict includes `--no-explicit-reexport` (`implicit_reexport = false`), which means that objects imported into a module will not be re-exported for import into other modules. Imports can be made into explicit exports with the syntax `from module import x as x` (i.e., changing from `import logging` to `import logging as logging`), or by including imports in `__all__`. This explicit import syntax can be confusing. Another option is to apply mypy overrides to any modules that need to leverage implicit exports. +- To learn type annotation basics, see the [Python typing module docs](https://docs.python.org/3/library/typing.html), [Python type annotations how-to](https://docs.python.org/3/howto/annotations.html), the [Real Python type checking tutorial](https://realpython.com/python-type-checking/), and [this gist](https://gist.github.com/987bdc6263217895d4bf03d0a5ff114c). +- Type annotations are not used at runtime. The standard library `typing` module includes a `TYPE_CHECKING` constant that is `False` at runtime, but `True` when conducting static type checking prior to runtime. Type imports are included under `if TYPE_CHECKING:` conditions so that they are not imported at runtime. These conditions are ignored when calculating test coverage. +- Type annotations can be provided inline or in separate stub files. Much of the Python standard library is annotated with stubs. For example, the Python standard library [`logging.config` module uses type stubs](https://github.com/python/typeshed/blob/main/stdlib/logging/config.pyi). The typeshed types for the `logging.config` module are used solely for type-checking usage of the `logging.config` module itself. They cannot be imported and used to type annotate other modules. +- The standard library `typing` module includes a `NoReturn` type. This would seem useful for [unreachable code](https://typing.readthedocs.io/en/stable/source/unreachable.html), including functions that do not return a value, such as test functions. Unfortunately mypy reports an error when using `NoReturn`, "Implicit return in function which does not return (misc)." To avoid headaches from the opaque "misc" category of [mypy errors](https://mypy.readthedocs.io/en/stable/error_code_list.html), these functions are annotated as returning `None`. +- [Mypy](https://mypy.readthedocs.io/en/stable/) is used for type-checking. [Mypy configuration](https://mypy.readthedocs.io/en/stable/config_file.html) is included in _pyproject.toml_. +- Mypy strict mode is enabled. Strict includes `--no-explicit-reexport` (`implicit_reexport = false`), which means that objects imported into a module will not be re-exported for import into other modules. Imports can be made into explicit exports with the syntax `from module import x as x` (i.e., changing from `import logging` to `import logging as logging`), or by including imports in `__all__`. This explicit import syntax can be confusing. Another option is to apply mypy overrides to any modules that need to leverage implicit exports. ### Spell check @@ -264,40 +264,40 @@ See the [Cloudflare R2 docs](https://developers.cloudflare.com/r2/) for further ### Merges -- **The default branch is `develop`.** -- **PRs should be merged into `develop`.** Head branches are deleted automatically after PRs are merged. -- **The only merges to `main` should be fast-forward merges from `develop`.** -- **Branch protection is enabled on `develop` and `main`.** - - `develop`: - - Require signed commits - - Include administrators - - Allow force pushes - - `main`: - - Require signed commits - - Include administrators - - Do not allow force pushes - - Require status checks to pass before merging (commits must have previously been pushed to `develop` and passed all checks) +- **The default branch is `develop`.** +- **PRs should be merged into `develop`.** Head branches are deleted automatically after PRs are merged. +- **The only merges to `main` should be fast-forward merges from `develop`.** +- **Branch protection is enabled on `develop` and `main`.** + - `develop`: + - Require signed commits + - Include administrators + - Allow force pushes + - `main`: + - Require signed commits + - Include administrators + - Do not allow force pushes + - Require status checks to pass before merging (commits must have previously been pushed to `develop` and passed all checks) ### Releases -- **To create a release:** - - Bump the version number in `fastenv.__version__` with `hatch version` and commit the changes to `develop`. - - Follow [SemVer](https://semver.org/) guidelines when choosing a version number. Note that [PEP 440](https://peps.python.org/pep-0440/) Python version specifiers and SemVer version specifiers differ, particularly with regard to specifying prereleases. Use syntax compatible with both. - - The PEP 440 default (like `1.0.0a0`) is different from SemVer. Hatch and PyPI will use this syntax by default. - - An alternative form of the Python prerelease syntax permitted in PEP 440 (like `1.0.0-alpha.0`) is compatible with SemVer, and this form should be used when tagging releases. As Hatch uses PEP 440 syntax by default, prerelease versions need to be written directly into `fastenv.__version__`. - - Examples of acceptable tag names: `1.0.0`, `1.0.0-alpha.0`, `1.0.0-beta.1` - - Push to `develop` and verify all CI checks pass. - - Fast-forward merge to `main`, push, and verify all CI checks pass. - - Create an [annotated and signed Git tag](https://www.git-scm.com/book/en/v2/Git-Basics-Tagging). - - List PRs and commits in the tag message: +- **To create a release:** + - Bump the version number in `fastenv.__version__` with `hatch version` and commit the changes to `develop`. + - Follow [SemVer](https://semver.org/) guidelines when choosing a version number. Note that [PEP 440](https://peps.python.org/pep-0440/) Python version specifiers and SemVer version specifiers differ, particularly with regard to specifying prereleases. Use syntax compatible with both. + - The PEP 440 default (like `1.0.0a0`) is different from SemVer. Hatch and PyPI will use this syntax by default. + - An alternative form of the Python prerelease syntax permitted in PEP 440 (like `1.0.0-alpha.0`) is compatible with SemVer, and this form should be used when tagging releases. As Hatch uses PEP 440 syntax by default, prerelease versions need to be written directly into `fastenv.__version__`. + - Examples of acceptable tag names: `1.0.0`, `1.0.0-alpha.0`, `1.0.0-beta.1` + - Push to `develop` and verify all CI checks pass. + - Fast-forward merge to `main`, push, and verify all CI checks pass. + - Create an [annotated and signed Git tag](https://www.git-scm.com/book/en/v2/Git-Basics-Tagging). + - List PRs and commits in the tag message: ```sh git log --pretty=format:"- %s (%h)" \ "$(git describe --abbrev=0 --tags)"..HEAD ``` - - Omit the leading `v` (use `1.0.0` instead of `v1.0.0`) - - Example: `git tag -a -s 1.0.0` - - Push the tag. GitHub Actions will build and publish the Python package and update the changelog. - - Squash and merge the changelog PR, removing any [`Co-authored-by` trailers](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors) before merging. + - Omit the leading `v` (use `1.0.0` instead of `v1.0.0`) + - Example: `git tag -a -s 1.0.0` + - Push the tag. GitHub Actions will build and publish the Python package and update the changelog. + - Squash and merge the changelog PR, removing any [`Co-authored-by` trailers](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors) before merging. ### Deployments @@ -305,7 +305,7 @@ Documentation is built with [Material for MkDocs](https://squidfunk.github.io/mk [Vercel build configuration](https://vercel.com/docs/build-step): -- Build command: `python3 -m pip install 'mkdocs-material>=9,<10' && mkdocs build --site-dir public`. **The version of `mkdocs-material` installed on Vercel is independent of the version listed in _pyproject.toml_. If the version of `mkdocs-material` is updated in _pyproject.toml_, it must also be updated in the Vercel build configuration.** -- Output directory: `public` (default) +- Build command: `python3 -m pip install 'mkdocs-material>=9,<10' && mkdocs build --site-dir public`. **The version of `mkdocs-material` installed on Vercel is independent of the version listed in _pyproject.toml_. If the version of `mkdocs-material` is updated in _pyproject.toml_, it must also be updated in the Vercel build configuration.** +- Output directory: `public` (default) [Vercel site configuration](https://vercel.com/docs/configuration) is specified in _vercel.json_. diff --git a/docs/environment.md b/docs/environment.md index 17a539a..a46b5cf 100644 --- a/docs/environment.md +++ b/docs/environment.md @@ -8,9 +8,9 @@ The implementation of `fastenv.DotEnv` is based on `os.environ`, and it inherits Practically speaking, "superset of `os.environ`" means: -- **When an environment variable is set in an instance of `class DotEnv`, it is also set in `os.environ`**. -- **When an environment variable is deleted from an instance of `class DotEnv`, it is also deleted from `os.environ`**. -- **When an environment variable is set directly with `os.environ`, it is not automatically set in instances of `class DotEnv`.** `os.environ` contains variables specific to the local environment, such as `os.environ["HOME"]`, so these variables are not included in `class DotEnv` by default. +- **When an environment variable is set in an instance of `class DotEnv`, it is also set in `os.environ`**. +- **When an environment variable is deleted from an instance of `class DotEnv`, it is also deleted from `os.environ`**. +- **When an environment variable is set directly with `os.environ`, it is not automatically set in instances of `class DotEnv`.** `os.environ` contains variables specific to the local environment, such as `os.environ["HOME"]`, so these variables are not included in `class DotEnv` by default. ## Getting started diff --git a/docs/index.md b/docs/index.md index 3a8c8dc..085272f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -15,11 +15,11 @@ fastenv [\[fæst iː ən v\]](https://en.wikipedia.org/wiki/Help:IPA/English) is This project aims to: -- [x] **Replace the aging [python-dotenv](https://github.com/theskumar/python-dotenv) project** with a similar, but more intuitive API, and modern syntax and tooling. -- [x] **Implement asynchronous file I/O**. Reading and writing files can be done asynchronously with packages like [AnyIO](https://github.com/agronholm/anyio). -- [x] **Implement asynchronous object storage integration**. Dotenv files are commonly kept in cloud object storage, but environment variable management packages typically don't integrate with object storage clients. Additional logic is therefore required to download _.env_ files from object storage prior to loading environment variables. This project aims to integrate with S3-compatible object storage, with a focus on downloading and uploading file objects. -- [ ] **Read settings from TOML**. [It's all about _pyproject.toml_ now](https://snarky.ca/what-the-heck-is-pyproject-toml/). The Python community has pushed [PEP 517](https://www.python.org/dev/peps/pep-0517/) build tooling and [PEP 518](https://www.python.org/dev/peps/pep-0518/) build requirements forward, and [even `setuptools` has come around](https://setuptools.readthedocs.io/en/latest/build_meta.html). [PEP 621](https://www.python.org/dev/peps/pep-0621/) defined how to store package metadata and dependencies in _pyproject.toml_. Why don't we use the metadata from our _pyproject.toml_ files in our Python applications? -- [ ] **Unify settings management for FastAPI**. [Uvicorn](https://www.uvicorn.org/), [Starlette](https://www.starlette.io/config/), and _[pydantic](https://pydantic-docs.helpmanual.io/usage/settings/)_ each have their own ways of loading environment variables and configuring application settings. This means that, when [configuring a FastAPI application](https://fastapi.tiangolo.com/advanced/settings/), there are at least three different settings management tools available, each with their own pros and cons. It would be helpful to address the limitations of each of these options, potentially providing a similar, improved API for each one. +- [x] **Replace the aging [python-dotenv](https://github.com/theskumar/python-dotenv) project** with a similar, but more intuitive API, and modern syntax and tooling. +- [x] **Implement asynchronous file I/O**. Reading and writing files can be done asynchronously with packages like [AnyIO](https://github.com/agronholm/anyio). +- [x] **Implement asynchronous object storage integration**. Dotenv files are commonly kept in cloud object storage, but environment variable management packages typically don't integrate with object storage clients. Additional logic is therefore required to download _.env_ files from object storage prior to loading environment variables. This project aims to integrate with S3-compatible object storage, with a focus on downloading and uploading file objects. +- [ ] **Read settings from TOML**. [It's all about _pyproject.toml_ now](https://snarky.ca/what-the-heck-is-pyproject-toml/). The Python community has pushed [PEP 517](https://www.python.org/dev/peps/pep-0517/) build tooling and [PEP 518](https://www.python.org/dev/peps/pep-0518/) build requirements forward, and [even `setuptools` has come around](https://setuptools.readthedocs.io/en/latest/build_meta.html). [PEP 621](https://www.python.org/dev/peps/pep-0621/) defined how to store package metadata and dependencies in _pyproject.toml_. Why don't we use the metadata from our _pyproject.toml_ files in our Python applications? +- [ ] **Unify settings management for FastAPI**. [Uvicorn](https://www.uvicorn.org/), [Starlette](https://www.starlette.io/config/), and _[pydantic](https://pydantic-docs.helpmanual.io/usage/settings/)_ each have their own ways of loading environment variables and configuring application settings. This means that, when [configuring a FastAPI application](https://fastapi.tiangolo.com/advanced/settings/), there are at least three different settings management tools available, each with their own pros and cons. It would be helpful to address the limitations of each of these options, potentially providing a similar, improved API for each one. The source code is 100% type-annotated and unit-tested. diff --git a/pyproject.toml b/pyproject.toml index 952026a..1b16130 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,13 +87,13 @@ check = [ "ruff check", "ruff format --check", "mypy", - "npx -s -y prettier@'^3' . --check", + "npx -s -y prettier@'^3.4' . --check", "npx -s -y cspell --dot --gitignore *.md **/*.md", ] format = [ "ruff check --fix", "ruff format", - "npx -s -y prettier@'^3' . --write", + "npx -s -y prettier@'^3.4' . --write", ] [tool.hatch.envs.docs]