diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 000000000..664a98426 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,22 @@ +{ + "permissions": { + "allow": [ + "Bash(mkdir:*)", + "Bash(gh issue create:*)", + "Bash(gh issue view:*)", + "Bash(mise run test:*)", + "Bash(mise ls:*)", + "Bash(mise tasks:*)", + "Bash(pre-commit:*)", + "Bash(rm:*)", + "WebFetch(domain:docs.github.com)", + "Bash(git add:*)", + "Bash(python -m pytest application/datamanager/tests -v)", + "Bash(uv pip:*)", + "Bash(cat:*)", + "Bash(mise run:*)", + "Bash(gh issue close:*)" + ], + "deny": [] + } +} diff --git a/.flox/env/manifest.lock b/.flox/env/manifest.lock index 0f78717bb..ff15369b9 100644 --- a/.flox/env/manifest.lock +++ b/.flox/env/manifest.lock @@ -6,6 +6,12 @@ "mise": { "pkg-path": "mise" }, + "pulumi": { + "pkg-path": "pulumi" + }, + "pulumi-python": { + "pkg-path": "pulumiPackages.pulumi-python" + }, "ruff": { "pkg-path": "ruff" }, @@ -14,10 +20,11 @@ }, "vulture": { "pkg-path": "python313Packages.vulture" + }, + "yamllint": { + "pkg-path": "yamllint" } }, - "hook": {}, - "profile": {}, "options": { "systems": [ "aarch64-darwin", @@ -43,6 +50,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T04:19:31.165669Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -72,6 +80,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T04:37:29.329193Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -101,6 +110,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T04:54:31.864641Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -130,6 +140,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T05:16:05.941930Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -144,6 +155,246 @@ "group": "toplevel", "priority": 5 }, + { + "attr_path": "pulumi", + "broken": false, + "derivation": "/nix/store/q4gmwrcdgfky0a1c54425p5lrpkc40xv-pulumi-3.162.0.drv", + "description": "Pulumi is a cloud development platform that makes creating cloud programs easy and productive", + "install_id": "pulumi", + "license": "Apache-2.0", + "locked_url": "https://github.com/flox/nixpkgs?rev=979daf34c8cacebcd917d540070b52a3c2b9b16e", + "name": "pulumi-3.162.0", + "pname": "pulumi", + "rev": "979daf34c8cacebcd917d540070b52a3c2b9b16e", + "rev_count": 793735, + "rev_date": "2025-05-04T03:14:55Z", + "scrape_date": "2025-05-05T04:19:37.674963Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "3.162.0", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/0ylbamwgdddnrc306m7lcjj1951wsjim-pulumi-3.162.0" + }, + "system": "aarch64-darwin", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "pulumi", + "broken": false, + "derivation": "/nix/store/j843870kk1mzi10bbnnsrxspgb1lz646-pulumi-3.162.0.drv", + "description": "Pulumi is a cloud development platform that makes creating cloud programs easy and productive", + "install_id": "pulumi", + "license": "Apache-2.0", + "locked_url": "https://github.com/flox/nixpkgs?rev=979daf34c8cacebcd917d540070b52a3c2b9b16e", + "name": "pulumi-3.162.0", + "pname": "pulumi", + "rev": "979daf34c8cacebcd917d540070b52a3c2b9b16e", + "rev_count": 793735, + "rev_date": "2025-05-04T03:14:55Z", + "scrape_date": "2025-05-05T04:37:42.099378Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "3.162.0", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/nj7liqz947djg171ccm8hypqy6md44l8-pulumi-3.162.0" + }, + "system": "aarch64-linux", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "pulumi", + "broken": false, + "derivation": "/nix/store/dq5wpxlz56ilza5yadylv8m1srbl88ai-pulumi-3.162.0.drv", + "description": "Pulumi is a cloud development platform that makes creating cloud programs easy and productive", + "install_id": "pulumi", + "license": "Apache-2.0", + "locked_url": "https://github.com/flox/nixpkgs?rev=979daf34c8cacebcd917d540070b52a3c2b9b16e", + "name": "pulumi-3.162.0", + "pname": "pulumi", + "rev": "979daf34c8cacebcd917d540070b52a3c2b9b16e", + "rev_count": 793735, + "rev_date": "2025-05-04T03:14:55Z", + "scrape_date": "2025-05-05T04:54:38.435341Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "3.162.0", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/xkvdqqrmdr1zbb6yjw1br8w1apnrsn22-pulumi-3.162.0" + }, + "system": "x86_64-darwin", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "pulumi", + "broken": false, + "derivation": "/nix/store/vdp26qmdcchb7rq1a9mb3jdxlf0y34qj-pulumi-3.162.0.drv", + "description": "Pulumi is a cloud development platform that makes creating cloud programs easy and productive", + "install_id": "pulumi", + "license": "Apache-2.0", + "locked_url": "https://github.com/flox/nixpkgs?rev=979daf34c8cacebcd917d540070b52a3c2b9b16e", + "name": "pulumi-3.162.0", + "pname": "pulumi", + "rev": "979daf34c8cacebcd917d540070b52a3c2b9b16e", + "rev_count": 793735, + "rev_date": "2025-05-04T03:14:55Z", + "scrape_date": "2025-05-05T05:16:19.837493Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "3.162.0", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/m7wi8smy3xkyf5rrlzh73z4d5ck4ic5p-pulumi-3.162.0" + }, + "system": "x86_64-linux", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "pulumiPackages.pulumi-python", + "broken": false, + "derivation": "/nix/store/csks3x6072jsy3flm0ni1l47lndw6vkx-pulumi-python-3.162.0.drv", + "description": "Language host for Pulumi programs written in Python", + "install_id": "pulumi-python", + "license": "Apache-2.0", + "locked_url": "https://github.com/flox/nixpkgs?rev=979daf34c8cacebcd917d540070b52a3c2b9b16e", + "name": "pulumi-python-3.162.0", + "pname": "pulumi-python", + "rev": "979daf34c8cacebcd917d540070b52a3c2b9b16e", + "rev_count": 793735, + "rev_date": "2025-05-04T03:14:55Z", + "scrape_date": "2025-05-05T04:19:37.684088Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "3.162.0", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/n71vz5rsqnpw6wszx982rcry5xkcbpgs-pulumi-python-3.162.0" + }, + "system": "aarch64-darwin", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "pulumiPackages.pulumi-python", + "broken": false, + "derivation": "/nix/store/hrss3x4h3j22w497gd00qy5jwhpc2g4b-pulumi-python-3.162.0.drv", + "description": "Language host for Pulumi programs written in Python", + "install_id": "pulumi-python", + "license": "Apache-2.0", + "locked_url": "https://github.com/flox/nixpkgs?rev=979daf34c8cacebcd917d540070b52a3c2b9b16e", + "name": "pulumi-python-3.162.0", + "pname": "pulumi-python", + "rev": "979daf34c8cacebcd917d540070b52a3c2b9b16e", + "rev_count": 793735, + "rev_date": "2025-05-04T03:14:55Z", + "scrape_date": "2025-05-05T04:37:42.113974Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "3.162.0", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/dcgz4fzwcjh9834x1qsv14p1i8ib9pv8-pulumi-python-3.162.0" + }, + "system": "aarch64-linux", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "pulumiPackages.pulumi-python", + "broken": false, + "derivation": "/nix/store/704isa4xv1xxwv6cghga55iicjmcl2ih-pulumi-python-3.162.0.drv", + "description": "Language host for Pulumi programs written in Python", + "install_id": "pulumi-python", + "license": "Apache-2.0", + "locked_url": "https://github.com/flox/nixpkgs?rev=979daf34c8cacebcd917d540070b52a3c2b9b16e", + "name": "pulumi-python-3.162.0", + "pname": "pulumi-python", + "rev": "979daf34c8cacebcd917d540070b52a3c2b9b16e", + "rev_count": 793735, + "rev_date": "2025-05-04T03:14:55Z", + "scrape_date": "2025-05-05T04:54:38.444512Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "3.162.0", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/a1cmahmxygihhi5b9z04dgwmd1prl1bl-pulumi-python-3.162.0" + }, + "system": "x86_64-darwin", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "pulumiPackages.pulumi-python", + "broken": false, + "derivation": "/nix/store/jccr0phqmfwacr7pas9hmalxhvaa6kpk-pulumi-python-3.162.0.drv", + "description": "Language host for Pulumi programs written in Python", + "install_id": "pulumi-python", + "license": "Apache-2.0", + "locked_url": "https://github.com/flox/nixpkgs?rev=979daf34c8cacebcd917d540070b52a3c2b9b16e", + "name": "pulumi-python-3.162.0", + "pname": "pulumi-python", + "rev": "979daf34c8cacebcd917d540070b52a3c2b9b16e", + "rev_count": 793735, + "rev_date": "2025-05-04T03:14:55Z", + "scrape_date": "2025-05-05T05:16:19.852933Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "3.162.0", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/0mnamh3p4j6fffy8la6mck3im2kq7ins-pulumi-python-3.162.0" + }, + "system": "x86_64-linux", + "group": "toplevel", + "priority": 5 + }, { "attr_path": "ruff", "broken": false, @@ -159,6 +410,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T04:20:01.303799Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -188,6 +440,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T04:38:18.124702Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -217,6 +470,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T04:55:01.974104Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -246,6 +500,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T05:16:57.964005Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -275,6 +530,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T04:20:25.534043Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -304,6 +560,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T04:38:52.133165Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -333,6 +590,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T04:55:26.025989Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -362,6 +620,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T05:17:33.646871Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -391,6 +650,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T04:19:56.681364Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -421,6 +681,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T04:38:11.017366Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -451,6 +712,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T04:54:57.351040Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -481,6 +743,7 @@ "rev_date": "2025-05-04T03:14:55Z", "scrape_date": "2025-05-05T05:16:50.153939Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, @@ -495,6 +758,130 @@ "system": "x86_64-linux", "group": "toplevel", "priority": 5 + }, + { + "attr_path": "yamllint", + "broken": false, + "derivation": "/nix/store/lfphdm6fmfba1654is7y5djg4pscwinp-python3.12-yamllint-1.37.0.drv", + "description": "Linter for YAML files", + "install_id": "yamllint", + "license": "GPL-3.0-or-later", + "locked_url": "https://github.com/flox/nixpkgs?rev=979daf34c8cacebcd917d540070b52a3c2b9b16e", + "name": "python3.12-yamllint-1.37.0", + "pname": "yamllint", + "rev": "979daf34c8cacebcd917d540070b52a3c2b9b16e", + "rev_count": 793735, + "rev_date": "2025-05-04T03:14:55Z", + "scrape_date": "2025-05-05T04:20:32.757794Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "1.37.0", + "outputs_to_install": [ + "out" + ], + "outputs": { + "dist": "/nix/store/7375pc0w9qqc1f5wcbg8pwclw0k9gdas-python3.12-yamllint-1.37.0-dist", + "out": "/nix/store/lrcb38xsf82yzj633jkrcyhsqv56jx88-python3.12-yamllint-1.37.0" + }, + "system": "aarch64-darwin", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "yamllint", + "broken": false, + "derivation": "/nix/store/ni7y8jbfnqyvdx4vxia7n0rv7b104smj-python3.12-yamllint-1.37.0.drv", + "description": "Linter for YAML files", + "install_id": "yamllint", + "license": "GPL-3.0-or-later", + "locked_url": "https://github.com/flox/nixpkgs?rev=979daf34c8cacebcd917d540070b52a3c2b9b16e", + "name": "python3.12-yamllint-1.37.0", + "pname": "yamllint", + "rev": "979daf34c8cacebcd917d540070b52a3c2b9b16e", + "rev_count": 793735, + "rev_date": "2025-05-04T03:14:55Z", + "scrape_date": "2025-05-05T04:39:03.182314Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "1.37.0", + "outputs_to_install": [ + "out" + ], + "outputs": { + "dist": "/nix/store/9zj9za1vxywa3qig1dzc9s3na9k927nn-python3.12-yamllint-1.37.0-dist", + "out": "/nix/store/3qfpb8zji71qlcdxb723nf8id1r1aycd-python3.12-yamllint-1.37.0" + }, + "system": "aarch64-linux", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "yamllint", + "broken": false, + "derivation": "/nix/store/jfsg416ff82ss9n9c6nrnx6xkw4g193q-python3.12-yamllint-1.37.0.drv", + "description": "Linter for YAML files", + "install_id": "yamllint", + "license": "GPL-3.0-or-later", + "locked_url": "https://github.com/flox/nixpkgs?rev=979daf34c8cacebcd917d540070b52a3c2b9b16e", + "name": "python3.12-yamllint-1.37.0", + "pname": "yamllint", + "rev": "979daf34c8cacebcd917d540070b52a3c2b9b16e", + "rev_count": 793735, + "rev_date": "2025-05-04T03:14:55Z", + "scrape_date": "2025-05-05T04:55:33.294585Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "1.37.0", + "outputs_to_install": [ + "out" + ], + "outputs": { + "dist": "/nix/store/2dri4azs0vc18fgh2mkdy0crmwxa3vqa-python3.12-yamllint-1.37.0-dist", + "out": "/nix/store/2l3jnywmzbwmxda4lxn5h98ijwqqac68-python3.12-yamllint-1.37.0" + }, + "system": "x86_64-darwin", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "yamllint", + "broken": false, + "derivation": "/nix/store/d7v676hj869dwp61jdhqgy46dali6irp-python3.12-yamllint-1.37.0.drv", + "description": "Linter for YAML files", + "install_id": "yamllint", + "license": "GPL-3.0-or-later", + "locked_url": "https://github.com/flox/nixpkgs?rev=979daf34c8cacebcd917d540070b52a3c2b9b16e", + "name": "python3.12-yamllint-1.37.0", + "pname": "yamllint", + "rev": "979daf34c8cacebcd917d540070b52a3c2b9b16e", + "rev_count": 793735, + "rev_date": "2025-05-04T03:14:55Z", + "scrape_date": "2025-05-05T05:17:45.391634Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "1.37.0", + "outputs_to_install": [ + "out" + ], + "outputs": { + "dist": "/nix/store/g3kmvlal3hdmmyakcavr2ynkc8jcsqcy-python3.12-yamllint-1.37.0-dist", + "out": "/nix/store/hq43nmliiy6jr64rcz5adrzj39jpbk1k-python3.12-yamllint-1.37.0" + }, + "system": "x86_64-linux", + "group": "toplevel", + "priority": 5 } ] } \ No newline at end of file diff --git a/.flox/env/manifest.toml b/.flox/env/manifest.toml index 7f39981d1..9d1e0b130 100644 --- a/.flox/env/manifest.toml +++ b/.flox/env/manifest.toml @@ -1,21 +1,15 @@ version = 1 [install] -uv.pkg-path = "uv" mise.pkg-path = "mise" +pulumi.pkg-path = "pulumi" +pulumi-python.pkg-path = "pulumiPackages.pulumi-python" ruff.pkg-path = "ruff" +uv.pkg-path = "uv" vulture.pkg-path = "python313Packages.vulture" - -[vars] - -[hook] - -[profile] - -[services] +yamllint.pkg-path = "yamllint" [options] - systems = [ "aarch64-darwin", "aarch64-linux", diff --git a/.github/workflows/quality.yaml b/.github/workflows/quality.yaml index 49449345e..bef8a40d1 100644 --- a/.github/workflows/quality.yaml +++ b/.github/workflows/quality.yaml @@ -1,3 +1,4 @@ +--- name: Code quality check on: push @@ -13,4 +14,4 @@ jobs: - name: Run Python quality checks uses: flox/activate-action@v1 with: - command: mise tasks run python:lint + command: mise tasks run python:lint diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index 4d902162f..1304e5411 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -1,3 +1,4 @@ +--- name: Close stale issues and pull requests on: schedule: @@ -13,12 +14,16 @@ jobs: - name: Close stale issues and pull requests uses: actions/stale@v9 with: - stale-issue-message: 'Marked stale due to inactivity. Remove stale label or comment or this will be closed.' - stale-pr-message: 'Marked stale due to inactivity. Remove stale label or comment or this will be closed.' + stale-issue-message: >- + Marked stale due to inactivity. + Remove stale label or comment or this will be closed. + stale-pr-message: >- + Marked stale due to inactivity. + Remove stale label or comment or this will be closed. stale-issue-label: stale stale-pr-label: stale close-issue-message: 'Closed due to inactivity.' close-pr-message: 'Closed due to inactivity.' days-before-stale: 7 days-before-close: 7 - exempt-draft-pr: true \ No newline at end of file + exempt-draft-pr: true diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e807861e8..cdc1ef55b 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,3 +1,4 @@ +--- name: Test and coverage check on: push diff --git a/.gitignore b/.gitignore index f9f7a507b..8f4ebe966 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ .flox/run/ .env .python_coverage.* -__pycache__/ \ No newline at end of file +__pycache__/ +infrastructure/Pulumi.infrastructure.yaml diff --git a/.mise.toml b/.mise.toml index 37d379a04..6605f165c 100755 --- a/.mise.toml +++ b/.mise.toml @@ -64,3 +64,18 @@ docker run \ --publish 8080:8080 \ pocketsizefund/{{arg(name="service_name")}}:latest \ """ + + +[tasks."lint"] +depends = ["python:lint"] +description = "Run code quality checks" +run = """ +yamllint . +""" + +[tasks."infrastructure:up"] +description = "launch cloud infrastructure" +run = """ +cd infrastructure +uv run pulumi up +""" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 752103066..8bad8979c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,15 +1,16 @@ +--- repos: - repo: local hooks: - - id: quality - name: Python quality check - entry: mise run python:lint - pass_filenames: false - types: [file, python] - language: system - - id: test - name: Python test - entry: mise run python:test - pass_filenames: false - types: [file, python] - language: system + - id: quality + name: Python quality check + entry: mise run python:lint + pass_filenames: false + types: [file, python] + language: system + - id: test + name: Python test + entry: mise run python:test + pass_filenames: false + types: [file, python] + language: system diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..305997510 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,30 @@ +# PocketSizeFund Assistant Memory + +Always use mise tasks for running tests, linting, formatting. If there is not a command already present in .mise.toml, suggest creating one. + +## Code Style Guidelines + +Unless the code is complex, never use comments in the code. The code should speak for itself. + +## GitHub Issue Creation + +When asked to create a new GitHub issue: + +1. Follow the structure in template files: + - `.github/ISSUE_TEMPLATE/BUG.md` for bugs + - `.github/ISSUE_TEMPLATE/FEATURE.md` for new features +2. Include: + - A descriptive title (without [FEATURE|BUG] prefix) + - Explain why the feature is needed + - Detail the benefits it will bring + - Propose two implementation options (after considering at least five) + - For each option, include: + - Files that need updating + - Code diff of proposed changes + - Cost-benefit analysis + +## GitHub Issue Workflow + +1. After creating a ticket, it will be reviewed and possibly modified +2. Issues with "todo" status are prepared for implementation +3. When asked to look at ready tickets ready for implementation, search for Github issues with "in progress" status diff --git a/infrastructure/.python-version b/infrastructure/.python-version new file mode 100644 index 000000000..24ee5b1be --- /dev/null +++ b/infrastructure/.python-version @@ -0,0 +1 @@ +3.13 diff --git a/infrastructure/Pulumi.yaml b/infrastructure/Pulumi.yaml new file mode 100644 index 000000000..2bb26c685 --- /dev/null +++ b/infrastructure/Pulumi.yaml @@ -0,0 +1,3 @@ +name: pocketsizefund-infrastructure +runtime: python +description: Pocket Size Fund Infrastructure diff --git a/infrastructure/README.md b/infrastructure/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/infrastructure/__main__.py b/infrastructure/__main__.py new file mode 100644 index 000000000..17448e979 --- /dev/null +++ b/infrastructure/__main__.py @@ -0,0 +1,2 @@ +import topics # noqa: F401 +import cloud_run # noqa: F401 diff --git a/infrastructure/cloud_run.py b/infrastructure/cloud_run.py new file mode 100644 index 000000000..af7384ce5 --- /dev/null +++ b/infrastructure/cloud_run.py @@ -0,0 +1,56 @@ +from pulumi_gcp import cloudrun, pubsub, cloudscheduler +import base64 +from pulumi import Config +import project +import topics + +config = Config() + +alpaca_api_key = config.require_secret("ALPACA_API_KEY_ID") +alpaca_api_secret = config.require_secret("ALPACA_API_SECRET_KEY") + + +service = cloudrun.Service( + "datamanager", + location=project.REGION, + template=cloudrun.ServiceTemplateArgs( + spec=cloudrun.ServiceTemplateSpecArgs( + service_account_name=project.platform_service_account.email, + containers=[ + cloudrun.ServiceTemplateSpecContainerArgs( + image="pocketsizefund/datamanager:latest", + args=["--period=1"], + envs=[ + cloudrun.ServiceTemplateSpecContainerEnvArgs( + name="ALPACA_API_KEY_ID", value=alpaca_api_key + ), + cloudrun.ServiceTemplateSpecContainerEnvArgs( + name="ALPACA_API_SECRET_KEY", value=alpaca_api_secret + ), + ], + ) + ], + ), + ), +) + +subscription = pubsub.Subscription( + "datamanager-subscription", + topic=topics.datamanager_ping.id, + push_config=pubsub.SubscriptionPushConfigArgs( + push_endpoint=service.statuses[0].url, + oidc_token=pubsub.SubscriptionPushConfigOidcTokenArgs( + service_account_email=project.platform_service_account.email + ), + ), +) + +job = cloudscheduler.Job( + "datamanager-job", + schedule="0 * * * *", + time_zone="UTC", + pubsub_target=cloudscheduler.JobPubsubTargetArgs( + topic_name=topics.datamanager_ping.id, + data=base64.b64encode(b"{}").decode("utf-8"), + ), +) diff --git a/infrastructure/main.py b/infrastructure/main.py new file mode 100644 index 000000000..b263f37db --- /dev/null +++ b/infrastructure/main.py @@ -0,0 +1,6 @@ +def main(): + print("Hello from infrastructure!") + + +if __name__ == "__main__": + main() diff --git a/infrastructure/project.py b/infrastructure/project.py new file mode 100644 index 000000000..5a9fdfa2a --- /dev/null +++ b/infrastructure/project.py @@ -0,0 +1,24 @@ +import pulumi +from pulumi_gcp.projects import Service, IAMMember +from pulumi_gcp.serviceaccount import Account + +PROJECT = pulumi.Config("gcp").require("project") +REGION = pulumi.Config("gcp").require("region") + +Service("enable-run", project=PROJECT, service="run.googleapis.com") +Service("enable-eventarc", project=PROJECT, service="eventarc.googleapis.com") +Service("enable-secretmanager", project=PROJECT, service="secretmanager.googleapis.com") +Service("enable-pubsub", project=PROJECT, service="pubsub.googleapis.com") + +platform_service_account = Account( + "platform-service-account", + account_id="platform", + display_name="Platform-Wide Cloud Run Service Account", +) + +IAMMember( + "pubsub-token-access", + project=PROJECT, + role="roles/pubsub.subscriber", + member=platform_service_account.email.apply(lambda e: f"serviceAccount:{e}"), +) diff --git a/infrastructure/pyproject.toml b/infrastructure/pyproject.toml new file mode 100644 index 000000000..15258c90f --- /dev/null +++ b/infrastructure/pyproject.toml @@ -0,0 +1,10 @@ +[project] +name = "infrastructure" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.13" +dependencies = [ + "pulumi>=3.169.0", + "pulumi-gcp>=8.30.1", +] diff --git a/infrastructure/topics.py b/infrastructure/topics.py new file mode 100644 index 000000000..0c5d197e4 --- /dev/null +++ b/infrastructure/topics.py @@ -0,0 +1,3 @@ +from pulumi_gcp.pubsub import Topic + +datamanager_ping = Topic("datamanager-ping") diff --git a/pyproject.toml b/pyproject.toml index dee512082..aa96160f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,10 @@ dependencies = [ ] [tool.uv.workspace] -members = ["application/datamanager"] +members = [ + "application/datamanager", + "infrastructure", +] [tool.uv.sources] datamanager = { workspace = true } diff --git a/uv.lock b/uv.lock index ccba9a1fd..a9a423f51 100644 --- a/uv.lock +++ b/uv.lock @@ -5,6 +5,7 @@ requires-python = ">=3.13" [manifest] members = [ "datamanager", + "infrastructure", "pocketsizefund", ] @@ -30,6 +31,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916, upload-time = "2025-03-17T00:02:52.713Z" }, ] +[[package]] +name = "arpeggio" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/12/c4/516bb54456f85ad1947702ea4cef543a59de66d31a9887dbc3d9df36e3e1/Arpeggio-2.0.2.tar.gz", hash = "sha256:c790b2b06e226d2dd468e4fbfb5b7f506cec66416031fde1441cf1de2a0ba700", size = 766643, upload-time = "2023-07-09T12:30:04.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/4f/d28bf30a19d4649b40b501d531b44e73afada99044df100380fd9567e92f/Arpeggio-2.0.2-py2.py3-none-any.whl", hash = "sha256:f7c8ae4f4056a89e020c24c7202ac8df3e2bc84e416746f20b0da35bb1de0250", size = 55287, upload-time = "2023-07-09T12:30:01.87Z" }, +] + +[[package]] +name = "attrs" +version = "25.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, +] + [[package]] name = "certifi" version = "2025.4.26" @@ -111,6 +130,28 @@ requires-dist = [ { name = "uvicorn", specifier = ">=0.34.2" }, ] +[[package]] +name = "debugpy" +version = "1.8.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/75/087fe07d40f490a78782ff3b0a30e3968936854105487decdb33446d4b0e/debugpy-1.8.14.tar.gz", hash = "sha256:7cd287184318416850aa8b60ac90105837bb1e59531898c07569d197d2ed5322", size = 1641444, upload-time = "2025-04-10T19:46:10.981Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/e4/395c792b243f2367d84202dc33689aa3d910fb9826a7491ba20fc9e261f5/debugpy-1.8.14-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:329a15d0660ee09fec6786acdb6e0443d595f64f5d096fc3e3ccf09a4259033f", size = 2485676, upload-time = "2025-04-10T19:46:32.96Z" }, + { url = "https://files.pythonhosted.org/packages/ba/f1/6f2ee3f991327ad9e4c2f8b82611a467052a0fb0e247390192580e89f7ff/debugpy-1.8.14-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f920c7f9af409d90f5fd26e313e119d908b0dd2952c2393cd3247a462331f15", size = 4217514, upload-time = "2025-04-10T19:46:34.336Z" }, + { url = "https://files.pythonhosted.org/packages/79/28/b9d146f8f2dc535c236ee09ad3e5ac899adb39d7a19b49f03ac95d216beb/debugpy-1.8.14-cp313-cp313-win32.whl", hash = "sha256:3784ec6e8600c66cbdd4ca2726c72d8ca781e94bce2f396cc606d458146f8f4e", size = 5254756, upload-time = "2025-04-10T19:46:36.199Z" }, + { url = "https://files.pythonhosted.org/packages/e0/62/a7b4a57013eac4ccaef6977966e6bec5c63906dd25a86e35f155952e29a1/debugpy-1.8.14-cp313-cp313-win_amd64.whl", hash = "sha256:684eaf43c95a3ec39a96f1f5195a7ff3d4144e4a18d69bb66beeb1a6de605d6e", size = 5297119, upload-time = "2025-04-10T19:46:38.141Z" }, + { url = "https://files.pythonhosted.org/packages/97/1a/481f33c37ee3ac8040d3d51fc4c4e4e7e61cb08b8bc8971d6032acc2279f/debugpy-1.8.14-py2.py3-none-any.whl", hash = "sha256:5cd9a579d553b6cb9759a7908a41988ee6280b961f24f63336835d9418216a20", size = 5256230, upload-time = "2025-04-10T19:46:54.077Z" }, +] + +[[package]] +name = "dill" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/12/80/630b4b88364e9a8c8c5797f4602d0f76ef820909ee32f0bacb9f90654042/dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", size = 186976, upload-time = "2025-04-16T00:41:48.867Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" }, +] + [[package]] name = "duckdb" version = "1.2.2" @@ -141,6 +182,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/50/b3/b51f09c2ba432a576fe63758bddc81f78f0c6309d9e5c10d194313bf021e/fastapi-0.115.12-py3-none-any.whl", hash = "sha256:e94613d6c05e27be7ffebdd6ea5f388112e5e430c8f7d6494a9d1d88d43e814d", size = 95164, upload-time = "2025-03-23T22:55:42.101Z" }, ] +[[package]] +name = "grpcio" +version = "1.66.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/71/d1/49a96df4eb1d805cf546247df40636515416d2d5c66665e5129c8b4162a8/grpcio-1.66.2.tar.gz", hash = "sha256:563588c587b75c34b928bc428548e5b00ea38c46972181a4d8b75ba7e3f24231", size = 12489713, upload-time = "2024-09-28T12:44:01.429Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/31/8708a8dfb3f1ac89926c27c5dd17412764157a2959dbc5a606eaf8ac71f6/grpcio-1.66.2-cp313-cp313-linux_armv7l.whl", hash = "sha256:3b00efc473b20d8bf83e0e1ae661b98951ca56111feb9b9611df8efc4fe5d55d", size = 5004245, upload-time = "2024-09-28T12:38:50.596Z" }, + { url = "https://files.pythonhosted.org/packages/8b/37/0b57c3769efb3cc9ec97fcaa9f7243046660e7ed58c0faebc4ef315df92c/grpcio-1.66.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1caa38fb22a8578ab8393da99d4b8641e3a80abc8fd52646f1ecc92bcb8dee34", size = 10756749, upload-time = "2024-09-28T12:38:54.131Z" }, + { url = "https://files.pythonhosted.org/packages/bf/5a/425e995724a19a1b110340ed653bc7c5de8019d9fc84b3798a0f79c3eb31/grpcio-1.66.2-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:c408f5ef75cfffa113cacd8b0c0e3611cbfd47701ca3cdc090594109b9fcbaed", size = 5499666, upload-time = "2024-09-28T12:38:57.145Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e4/86a5c5ec40a6b683671a1d044ebca433812d99da8fcfc2889e9c43cecbd4/grpcio-1.66.2-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c806852deaedee9ce8280fe98955c9103f62912a5b2d5ee7e3eaa284a6d8d8e7", size = 6109578, upload-time = "2024-09-28T12:38:59.835Z" }, + { url = "https://files.pythonhosted.org/packages/2f/86/a86742f3deaa22385c3bff984c5947fc62d47d3fab26c508730037d027e5/grpcio-1.66.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f145cc21836c332c67baa6fc81099d1d27e266401565bf481948010d6ea32d46", size = 5763274, upload-time = "2024-09-28T12:39:02.287Z" }, + { url = "https://files.pythonhosted.org/packages/c3/61/b9a2a4345dea0a354c4ed8ac7aacbdd0ff986acbc8f92680213cf3d2faa3/grpcio-1.66.2-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:73e3b425c1e155730273f73e419de3074aa5c5e936771ee0e4af0814631fb30a", size = 6450416, upload-time = "2024-09-28T12:39:05.06Z" }, + { url = "https://files.pythonhosted.org/packages/50/b9/ad303ce75d8cd71d855a661519aa160ce42f27498f589f1ae6d9f8c5e8ac/grpcio-1.66.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:9c509a4f78114cbc5f0740eb3d7a74985fd2eff022971bc9bc31f8bc93e66a3b", size = 6040045, upload-time = "2024-09-28T12:39:08.214Z" }, + { url = "https://files.pythonhosted.org/packages/ac/b3/8db1873e3240ef1672ba87b89e949ece367089e29e4d221377bfdd288bd3/grpcio-1.66.2-cp313-cp313-win32.whl", hash = "sha256:20657d6b8cfed7db5e11b62ff7dfe2e12064ea78e93f1434d61888834bc86d75", size = 3537126, upload-time = "2024-09-28T12:39:10.655Z" }, + { url = "https://files.pythonhosted.org/packages/a2/df/133216989fe7e17caeafd7ff5b17cc82c4e722025d0b8d5d2290c11fe2e6/grpcio-1.66.2-cp313-cp313-win_amd64.whl", hash = "sha256:fb70487c95786e345af5e854ffec8cb8cc781bcc5df7930c4fbb7feaa72e1cdf", size = 4278018, upload-time = "2024-09-28T12:39:13.196Z" }, +] + [[package]] name = "h11" version = "0.16.0" @@ -187,6 +245,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, ] +[[package]] +name = "infrastructure" +version = "0.1.0" +source = { virtual = "infrastructure" } +dependencies = [ + { name = "pulumi" }, + { name = "pulumi-gcp" }, +] + +[package.metadata] +requires-dist = [ + { name = "pulumi", specifier = ">=3.169.0" }, + { name = "pulumi-gcp", specifier = ">=8.30.1" }, +] + [[package]] name = "iniconfig" version = "2.1.0" @@ -205,6 +278,28 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] +[[package]] +name = "parver" +version = "0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "arpeggio" }, + { name = "attrs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cc/e5/1c774688a90f0b76e872e30f6f1ba3f5e14056cd0d96a684047d4a986226/parver-0.5.tar.gz", hash = "sha256:b9fde1e6bb9ce9f07e08e9c4bea8d8825c5e78e18a0052d02e02bf9517eb4777", size = 26908, upload-time = "2023-10-03T21:06:54.506Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/4c/f98024021bef4d44dce3613feebd702c7ad8883f777ff8488384c59e9774/parver-0.5-py3-none-any.whl", hash = "sha256:2281b187276c8e8e3c15634f62287b2fb6fe0efe3010f739a6bd1e45fa2bf2b2", size = 15172, upload-time = "2023-10-03T21:06:52.796Z" }, +] + +[[package]] +name = "pip" +version = "25.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/59/de/241caa0ca606f2ec5fe0c1f4261b0465df78d786a38da693864a116c37f4/pip-25.1.1.tar.gz", hash = "sha256:3de45d411d308d5054c2168185d8da7f9a2cd753dbac8acbfa88a8909ecd9077", size = 1940155, upload-time = "2025-05-02T15:14:02.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/a2/d40fb2460e883eca5199c62cfc2463fd261f760556ae6290f88488c362c0/pip-25.1.1-py3-none-any.whl", hash = "sha256:2913a38a2abf4ea6b64ab507bd9e967f3b53dc1ede74b01b0931e1ce548751af", size = 1825227, upload-time = "2025-05-02T15:13:59.102Z" }, +] + [[package]] name = "pluggy" version = "1.5.0" @@ -245,6 +340,51 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/45/fd/9039f609d76b3ebb13777f289502a00b52709aea5c35aed01d1090ac142f/polars-1.29.0-cp39-abi3-win_arm64.whl", hash = "sha256:0c105b07b980b77fe88c3200b015bf4695e53185385f0f244c13e2d1027c7bbf", size = 31298689, upload-time = "2025-04-30T20:56:33.449Z" }, ] +[[package]] +name = "protobuf" +version = "4.25.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/74/63/84fdeac1f03864c2b8b9f0b7fe711c4af5f95759ee281d2026530086b2f5/protobuf-4.25.7.tar.gz", hash = "sha256:28f65ae8c14523cc2c76c1e91680958700d3eac69f45c96512c12c63d9a38807", size = 380612, upload-time = "2025-04-24T02:56:58.685Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/ed/9a58076cfb8edc237c92617f1d3744660e9b4457d54f3c2fdf1a4bbae5c7/protobuf-4.25.7-cp310-abi3-win32.whl", hash = "sha256:dc582cf1a73a6b40aa8e7704389b8d8352da616bc8ed5c6cc614bdd0b5ce3f7a", size = 392457, upload-time = "2025-04-24T02:56:40.798Z" }, + { url = "https://files.pythonhosted.org/packages/28/b3/e00870528029fe252cf3bd6fa535821c276db3753b44a4691aee0d52ff9e/protobuf-4.25.7-cp310-abi3-win_amd64.whl", hash = "sha256:cd873dbddb28460d1706ff4da2e7fac175f62f2a0bebc7b33141f7523c5a2399", size = 413446, upload-time = "2025-04-24T02:56:44.199Z" }, + { url = "https://files.pythonhosted.org/packages/60/1d/f450a193f875a20099d4492d2c1cb23091d65d512956fb1e167ee61b4bf0/protobuf-4.25.7-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:4c899f09b0502eb39174c717ccf005b844ea93e31137c167ddcacf3e09e49610", size = 394248, upload-time = "2025-04-24T02:56:45.75Z" }, + { url = "https://files.pythonhosted.org/packages/c8/b8/ea88e9857484a0618c74121618b9e620fc50042de43cdabbebe1b93a83e0/protobuf-4.25.7-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:6d2f5dede3d112e573f0e5f9778c0c19d9f9e209727abecae1d39db789f522c6", size = 293717, upload-time = "2025-04-24T02:56:47.427Z" }, + { url = "https://files.pythonhosted.org/packages/a7/81/d0b68e9a9a76804113b6dedc6fffed868b97048bbe6f1bedc675bdb8523c/protobuf-4.25.7-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:d41fb7ae72a25fcb79b2d71e4247f0547a02e8185ed51587c22827a87e5736ed", size = 294636, upload-time = "2025-04-24T02:56:48.976Z" }, + { url = "https://files.pythonhosted.org/packages/17/d7/1e7c80cb2ea2880cfe38580dcfbb22b78b746640c9c13fc3337a6967dc4c/protobuf-4.25.7-py3-none-any.whl", hash = "sha256:e9d969f5154eaeab41404def5dcf04e62162178f4b9de98b2d3c1c70f5f84810", size = 156468, upload-time = "2025-04-24T02:56:56.957Z" }, +] + +[[package]] +name = "pulumi" +version = "3.169.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "debugpy" }, + { name = "dill" }, + { name = "grpcio" }, + { name = "pip" }, + { name = "protobuf" }, + { name = "pyyaml" }, + { name = "semver" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/f7/fdf271f5c576f380745c20c47812e98956f0871d3569125c93476ab44418/pulumi-3.169.0-py3-none-any.whl", hash = "sha256:8288d5baf63d280793d118c2df5708ed24327e59f20ecf3c86fc0900da2e8c38", size = 337496, upload-time = "2025-05-08T11:53:42.854Z" }, +] + +[[package]] +name = "pulumi-gcp" +version = "8.30.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "parver" }, + { name = "pulumi" }, + { name = "semver" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/37/5e45019b81317c98ebba738104777edc77a698708292213315af6bf8098d/pulumi_gcp-8.30.1.tar.gz", hash = "sha256:e32f21d47d35439140a47a467cbabee66790d57d8c7f900e51ee612129168035", size = 7586280, upload-time = "2025-05-13T12:51:37.136Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/fd/395e816595575576bf4dd29c44d03ce5402aebdb56ac6f0813f55b76e1df/pulumi_gcp-8.30.1-py3-none-any.whl", hash = "sha256:71687a8f16c0e05846d699956c7da79ed5b633afab3a65671de0163167a6c948", size = 9603797, upload-time = "2025-05-13T12:51:33.698Z" }, +] + [[package]] name = "pyarrow" version = "20.0.0" @@ -329,6 +469,32 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" }, ] +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, +] + +[[package]] +name = "semver" +version = "3.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/d1/d3159231aec234a59dd7d601e9dd9fe96f3afff15efd33c1070019b26132/semver-3.0.4.tar.gz", hash = "sha256:afc7d8c584a5ed0a11033af086e8af226a9c0b206f313e0301f8dd7b6b589602", size = 269730, upload-time = "2025-01-24T13:19:27.617Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/24/4d91e05817e92e3a61c8a21e08fd0f390f5301f1c448b137c57c4bc6e543/semver-3.0.4-py3-none-any.whl", hash = "sha256:9c824d87ba7f7ab4a1890799cec8596f15c1241cb473404ea1cb0c55e4b04746", size = 17912, upload-time = "2025-01-24T13:19:24.949Z" }, +] + [[package]] name = "sniffio" version = "1.3.1"