diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index e64bb01e..cb51d59d 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -35,6 +35,7 @@ branchProtectionRules: - "langchain-python-sdk-pr-py311 (toolbox-testing-438616)" - "langchain-python-sdk-pr-py310 (toolbox-testing-438616)" - "langchain-python-sdk-pr-py39 (toolbox-testing-438616)" + - "core-python-sdk-pr-py313 (toolbox-testing-438616)" requiredApprovingReviewCount: 1 requiresCodeOwnerReviews: true requiresStrictStatusChecks: true @@ -42,4 +43,4 @@ branchProtectionRules: # Set team access permissionRules: - team: senseai-eco - permission: admin \ No newline at end of file + permission: admin diff --git a/.github/workflows/lint-toolbox-core.yaml b/.github/workflows/lint-toolbox-core.yaml new file mode 100644 index 00000000..d9dd6ee6 --- /dev/null +++ b/.github/workflows/lint-toolbox-core.yaml @@ -0,0 +1,84 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: core +on: + pull_request: + paths: + - 'packages/toolbox-core/**' + - '!packages/toolbox-core/**/*.md' + pull_request_target: + types: [labeled] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + lint: + if: "${{ github.event.action != 'labeled' || github.event.label.name == 'tests: run' }}" + name: lint + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + defaults: + run: + working-directory: ./packages/toolbox-core + permissions: + contents: 'read' + issues: 'write' + pull-requests: 'write' + steps: + - name: Remove PR Label + if: "${{ github.event.action == 'labeled' && github.event.label.name == 'tests: run' }}" + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + try { + await github.rest.issues.removeLabel({ + name: 'tests: run', + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number + }); + } catch (e) { + console.log('Failed to remove label. Another job may have already removed it!'); + } + - name: Checkout code + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + ref: ${{ github.event.pull_request.head.sha }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + token: ${{ secrets.GITHUB_TOKEN }} + - name: Setup Python + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 + with: + python-version: "3.13" + + - name: Install library requirements + run: pip install -r requirements.txt + + - name: Install test requirements + run: pip install .[test] + + - name: Run linters + run: | + black --check . + isort --check . + + - name: Run type-check + env: + MYPYPATH: './src' + run: mypy --install-types --non-interactive --cache-dir=.mypy_cache/ -p toolbox_core \ No newline at end of file diff --git a/packages/toolbox-core/CHANGELOG.md b/packages/toolbox-core/CHANGELOG.md new file mode 100644 index 00000000..e69de29b diff --git a/packages/toolbox-core/DEVELOPER.md b/packages/toolbox-core/DEVELOPER.md new file mode 100644 index 00000000..d8d43a18 --- /dev/null +++ b/packages/toolbox-core/DEVELOPER.md @@ -0,0 +1,38 @@ +# Development + +Below are the details to set up a development environment and run tests. + +## Install +1. Clone the repository: + TODO: Correct repo URL + ```bash + git clone https://github.com/googleapis/genai-toolbox-langchain-python + ``` +1. Navigate to the package directory: + ```bash + cd genai-toolbox-langchain-python/packages/toolbox-core + ``` +1. Install the package in editable mode, so changes are reflected without + reinstall: + ```bash + pip install -e . + ``` +1. Make code changes and contribute to the SDK's development. +> [!TIP] +> Using `-e` option allows you to make changes to the SDK code and have +> those changes reflected immediately without reinstalling the package. + +## Test +1. Navigate to the package directory if needed: + ```bash + cd genai-toolbox-langchain-python/packages/toolbox-core + ``` +1. Install the SDK and test dependencies: + ```bash + pip install -e .[test] + ``` +1. Run tests and/or contribute to the SDK's development. + + ```bash + pytest + ``` diff --git a/packages/toolbox-core/README.md b/packages/toolbox-core/README.md new file mode 100644 index 00000000..a84b275a --- /dev/null +++ b/packages/toolbox-core/README.md @@ -0,0 +1,2 @@ +# GenAI toolbox core +# TODO: update readme \ No newline at end of file diff --git a/packages/toolbox-core/integration.cloudbuild.yaml b/packages/toolbox-core/integration.cloudbuild.yaml new file mode 100644 index 00000000..66c1f4f9 --- /dev/null +++ b/packages/toolbox-core/integration.cloudbuild.yaml @@ -0,0 +1,46 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +steps: + - id: Install library requirements + name: 'python:${_VERSION}' + args: + - install + - '-r' + - 'packages/toolbox-core/requirements.txt' + - '--user' + entrypoint: pip + - id: Install test requirements + name: 'python:${_VERSION}' + args: + - install + - 'packages/toolbox-core[test]' + - '--user' + entrypoint: pip + - id: Run integration tests + name: 'python:${_VERSION}' + env: + - TOOLBOX_URL=$_TOOLBOX_URL + - TOOLBOX_VERSION=$_TOOLBOX_VERSION + - GOOGLE_CLOUD_PROJECT=$PROJECT_ID + args: + - '-c' + - >- + python -m pytest packages/toolbox-core/tests/ + entrypoint: /bin/bash +options: + logging: CLOUD_LOGGING_ONLY +substitutions: + _VERSION: '3.13' + _TOOLBOX_VERSION: '0.2.1' \ No newline at end of file diff --git a/packages/toolbox-core/pyproject.toml b/packages/toolbox-core/pyproject.toml new file mode 100644 index 00000000..980360ae --- /dev/null +++ b/packages/toolbox-core/pyproject.toml @@ -0,0 +1,60 @@ +[project] +name = "toolbox-core" +dynamic = ["version"] +readme = "README.md" +description = "Python Base SDK for interacting with the Toolbox service" +license = {file = "LICENSE"} +requires-python = ">=3.9" +authors = [ + {name = "Google LLC", email = "googleapis-packages@google.com"} +] + +# TODO: Add deps +#dependencies = [ +#] + +classifiers = [ + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] + +# Tells setuptools that packages are under the 'src' directory +[tool.setuptools] +package-dir = {"" = "src"} + +[tool.setuptools.dynamic] +version = {attr = "toolbox_core.version.__version__"} + +[project.urls] +Homepage = "https://github.com/googleapis/genai-toolbox-langchain-python/blob/main/packages/toolbox-core" +Repository = "https://github.com/googleapis/genai-toolbox-langchain-python.git" +"Bug Tracker" = "https://github.com/googleapis/genai-toolbox-langchain-python/issues" +Changelog = "https://github.com/googleapis/genai-toolbox-langchain-python/blob/main/packages/toolbox-core/CHANGELOG.md" + +[project.optional-dependencies] +test = [ + "black[jupyter]==25.1.0", + "isort==6.0.1", + "mypy==1.15.0", + "pytest==8.3.5", +] +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[tool.black] +target-version = ['py39'] + +[tool.isort] +profile = "black" + +[tool.mypy] +python_version = "3.9" +warn_unused_configs = true +disallow_incomplete_defs = true diff --git a/packages/toolbox-core/requirements.txt b/packages/toolbox-core/requirements.txt new file mode 100644 index 00000000..e69de29b diff --git a/packages/toolbox-core/src/toolbox_core/__init__.py b/packages/toolbox-core/src/toolbox_core/__init__.py new file mode 100644 index 00000000..433463de --- /dev/null +++ b/packages/toolbox-core/src/toolbox_core/__init__.py @@ -0,0 +1,17 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from .client import DummyClass + +__all__ = ["DummyClass"] diff --git a/packages/toolbox-core/src/toolbox_core/client.py b/packages/toolbox-core/src/toolbox_core/client.py new file mode 100644 index 00000000..3caf79e1 --- /dev/null +++ b/packages/toolbox-core/src/toolbox_core/client.py @@ -0,0 +1,18 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +class DummyClass: + def __init__(self): + self.val = "dummy value" diff --git a/packages/toolbox-core/src/toolbox_core/py.typed b/packages/toolbox-core/src/toolbox_core/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/packages/toolbox-core/src/toolbox_core/version.py b/packages/toolbox-core/src/toolbox_core/version.py new file mode 100644 index 00000000..702896da --- /dev/null +++ b/packages/toolbox-core/src/toolbox_core/version.py @@ -0,0 +1,15 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +__version__ = "0.1.0" diff --git a/packages/toolbox-core/tests/test_core.py b/packages/toolbox-core/tests/test_core.py new file mode 100644 index 00000000..76ce659f --- /dev/null +++ b/packages/toolbox-core/tests/test_core.py @@ -0,0 +1,20 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from toolbox_core import DummyClass + + +class TestToolboxCore: + def test_dummy(self): + dummy_variable = DummyClass() + assert dummy_variable.val == "dummy value"