From 6529f59c8e460d2a669bf4f945808e29cc013b95 Mon Sep 17 00:00:00 2001 From: Mohammed Odeh Date: Thu, 22 Jan 2026 13:12:12 -0500 Subject: [PATCH 1/2] add changeset tooling --- Makefile | 38 +++- changesets/README.md | 61 +++++++ changesets/manage.py | 423 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 513 insertions(+), 9 deletions(-) create mode 100644 changesets/README.md create mode 100755 changesets/manage.py diff --git a/Makefile b/Makefile index cdcd567..f5cbfbd 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,21 @@ -.PHONY: generate generate-types generate-http test format typecheck install clean help +.PHONY: generate generate-types generate-http test format typecheck install clean help changeset changeset-status changeset-version changeset-changelog help: @echo "Available commands:" - @echo " make generate - Generate all code (types + HTTP client)" - @echo " make generate-types - Generate type definitions" - @echo " make generate-http - Generate HTTP client" - @echo " make test - Run tests" - @echo " make format - Format all Python files with ruff" - @echo " make typecheck - Run mypy type checking" - @echo " make install - Install all packages in dev mode" - @echo " make clean - Remove generated files and caches" + @echo " make generate - Generate all code (types + HTTP client)" + @echo " make generate-types - Generate type definitions" + @echo " make generate-http - Generate HTTP client" + @echo " make test - Run tests" + @echo " make format - Format all Python files with ruff" + @echo " make typecheck - Run mypy type checking" + @echo " make install - Install all packages in dev mode" + @echo " make clean - Remove generated files and caches" + @echo "" + @echo "Changeset commands:" + @echo " make changeset - Create a new changeset file" + @echo " make changeset-status - Show pending changesets" + @echo " make changeset-version - Apply version bumps from changesets" + @echo " make changeset-changelog - Generate changelogs from applied changesets" generate: generate-types generate-http @@ -49,3 +55,17 @@ clean: @find . -type d -name ".pytest_cache" -exec rm -rf {} + 2>/dev/null || true @find . -type d -name ".ruff_cache" -exec rm -rf {} + 2>/dev/null || true @echo "โœ… Cleanup complete" + +# Changeset management +changeset: + @python changesets/manage.py new + +changeset-status: + @python changesets/manage.py status + +changeset-version: + @python changesets/manage.py version + +changeset-changelog: + @python changesets/manage.py changelog + diff --git a/changesets/README.md b/changesets/README.md new file mode 100644 index 0000000..ed8aa89 --- /dev/null +++ b/changesets/README.md @@ -0,0 +1,61 @@ +# Changesets + +Declare version bumps and changelog entries for packages. + +## Usage + +### 1. Create a changeset + +```bash +make changeset +``` + +Runs an interactive wizard to create a new changeset file. Or create manually: + +```yaml +type: minor # patch | minor | major | beta +packages: [ http, sdk-types ] +changelog: |- + Your changelog message here +``` + +### 2. Apply version bumps + +```bash +make changeset-version +``` + +Updates `pyproject.toml` versions and moves changesets to `.changeset/applied/`. + +### 3. Generate changelogs + +```bash +make changeset-changelog +``` + +Updates `CHANGELOG.md` files and cleans up applied changesets. + +### 4. Check status + +```bash +make changeset-status +``` + +## Format Options + +**YAML array:** +```yaml +type: minor +packages: [ http, sdk-types ] +changelog: |- + Message +``` + +**YAML mapping (different bumps per package):** +```yaml +packages: + http: minor + sdk-types: patch +changelog: |- + Message +``` \ No newline at end of file diff --git a/changesets/manage.py b/changesets/manage.py new file mode 100755 index 0000000..4212a3a --- /dev/null +++ b/changesets/manage.py @@ -0,0 +1,423 @@ +#!/usr/bin/env python3 +"""Changeset management for Python SDK - similar to Kotlin's changesets system.""" + +import re +import sys +from dataclasses import dataclass +from datetime import date +from pathlib import Path +from typing import List, Dict, Optional +import shutil + + +@dataclass +class Changeset: + """Represents a changeset file with modules, type, and summary.""" + file: Path + modules: List[str] # e.g., ["api-key-stamper", "http", "sdk-types"] + type: str # patch | minor | major | beta + summary: str + + +class ChangesetManager: + """Manages changeset operations.""" + + def __init__(self, root_dir: Path): + self.root_dir = root_dir + self.changeset_dir = root_dir / ".changeset" + self.applied_dir = self.changeset_dir / "applied" + self.packages_dir = root_dir / "packages" + + def load_changesets(self, from_dir: Optional[Path] = None) -> List[Changeset]: + """Load changeset files from .changeset/ or specified directory.""" + target_dir = from_dir or self.changeset_dir + if not target_dir.exists(): + return [] + + files = sorted( + f for f in target_dir.iterdir() + if f.is_file() and f.suffix in {".yml", ".yaml", ".md"} + ) + + changesets = [] + for file in files: + parsed = self._parse_changeset(file) + changesets.extend(parsed) + + return changesets + + def _parse_changeset(self, file: Path) -> List[Changeset]: + """Parse a changeset file (YAML or Markdown front-matter).""" + text = file.read_text() + + # Try YAML array form first + # type: minor + # packages: [ api-key-stamper, http ] + # changelog: |- + # summary... + type_match = re.search(r'(?mi)^\s*type\s*:\s*"?(major|minor|patch|beta)"?\s*$', text) + array_match = re.search(r'(?ms)^\s*packages\s*:\s*\[(.*?)\]\s*$', text) + + if array_match: + packages = [ + p.strip().strip('"\'') + for p in array_match.group(1).split(',') + if p.strip() + ] + if packages: + bump_type = type_match.group(1).lower() if type_match else "patch" + summary = self._extract_changelog(text) + return [Changeset(file, packages, bump_type, summary)] + + # Try YAML mapping form + # packages: + # api-key-stamper: minor + # http: patch + mapping_match = re.search(r'(?ms)^\s*packages\s*:\s*\n(.*?)(^\S|\Z)', text) + if mapping_match: + entries = [] + for line in mapping_match.group(1).splitlines(): + entry_match = re.match(r'^\s+(.+?)\s*:\s*(major|minor|patch|beta)\s*$', line) + if entry_match: + entries.append((entry_match.group(1).strip(), entry_match.group(2).strip())) + + if entries: + summary = self._extract_changelog(text) + return [ + Changeset(file, [mod], bump, summary) + for mod, bump in entries + ] + + # Try Markdown front-matter + # --- + # type: minor + # packages: + # - api-key-stamper + # - http + # --- + # body... + fm_match = re.match(r'(?s)^---\s*(.*?)\s*---\s*(.*)$', text) + if fm_match: + front, body = fm_match.groups() + + type_fm = re.search(r'(?mi)^\s*type\s*:\s*"?(major|minor|patch|beta)"?\s*$', front) + packages_fm = re.findall(r'(?m)^\s*-\s*(.+)\s*$', front) + + if packages_fm: + bump_type = type_fm.group(1).lower() if type_fm else "patch" + return [Changeset(file, packages_fm, bump_type, body.strip())] + + return [] + + def _extract_changelog(self, text: str) -> str: + """Extract changelog content from YAML.""" + match = re.search(r'(?ms)^\s*changelog\s*:\s*\|-\s*\n(.*)$', text) + if not match: + return "" + body = match.group(1) + return '\n'.join(line.removeprefix(" ") for line in body.splitlines()).strip() + + def bump_version(self, version: str, bump: str) -> str: + """Bump a semantic version string.""" + match = re.match(r'^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z\.-]+))?$', version) + if not match: + return version + + major, minor, patch = int(match.group(1)), int(match.group(2)), int(match.group(3)) + pre = match.group(4) or "" + + bump = bump.lower() + if bump == "major": + return f"{major + 1}.0.0" + elif bump == "minor": + return f"{major}.{minor + 1}.0" + elif bump == "patch": + return f"{major}.{minor}.{patch + 1}" + elif bump == "beta": + core = f"{major}.{minor}.{patch}" + if not pre: + return f"{core}-beta.1" + parts = pre.split(".") + if parts[0].lower() == "beta": + num = int(parts[-1]) + 1 if parts[-1].isdigit() else 1 + base = ".".join(parts[:-1]) if len(parts) > 1 else "beta" + return f"{core}-{base}.{num}" + return f"{core}-beta.1" + return version + + def read_module_version(self, module_name: str) -> Optional[str]: + """Read version from module's pyproject.toml.""" + module_dir = self.packages_dir / module_name + pyproject = module_dir / "pyproject.toml" + + if not pyproject.exists(): + return None + + text = pyproject.read_text() + match = re.search(r'(?m)^\s*version\s*=\s*["\']([^"\']+)["\']', text) + return match.group(1) if match else None + + def write_module_version(self, module_name: str, new_version: str) -> bool: + """Write version to module's pyproject.toml.""" + module_dir = self.packages_dir / module_name + pyproject = module_dir / "pyproject.toml" + + if not pyproject.exists(): + return False + + text = pyproject.read_text() + pattern = r'(^\s*version\s*=\s*["\'])([^"\']+)(["\'])' + + if re.search(pattern, text, re.MULTILINE): + updated = re.sub(pattern, rf'\g<1>{new_version}\g<3>', text, flags=re.MULTILINE) + pyproject.write_text(updated) + return True + + return False + + +def cmd_new(manager: ChangesetManager): + """Interactive wizard to create a new changeset file.""" + print("๐Ÿ“ Create a new changeset\n") + + # Get bump type + print("Bump type:") + print(" 1) patch - Bug fixes, minor changes") + print(" 2) minor - New features (backwards-compatible)") + print(" 3) major - Breaking changes") + print(" 4) beta - Pre-release") + choice = input("\nSelect type [1-4]: ").strip() + + type_map = {"1": "patch", "2": "minor", "3": "major", "4": "beta"} + bump_type = type_map.get(choice, "patch") + + # Get packages + packages_list = [p.name for p in manager.packages_dir.iterdir() if p.is_dir() and not p.name.startswith('.')] + print(f"\nAvailable packages: {', '.join(packages_list)}") + packages_input = input("Packages (comma-separated): ").strip() + packages = [p.strip() for p in packages_input.split(',') if p.strip()] + + if not packages: + print("Error: At least one package is required") + sys.exit(1) + + # Get changelog + print("\nChangelog message (press Ctrl+D or Ctrl+Z when done):") + lines = [] + try: + while True: + line = input() + lines.append(line) + except EOFError: + pass + + changelog = '\n'.join(lines).strip() + if not changelog: + changelog = "No description provided" + + # Generate filename + name = input("\nChangeset filename (without extension): ").strip() + if not name: + name = f"change-{date.today().strftime('%Y%m%d')}" + + filepath = manager.changeset_dir / f"{name}.yml" + if filepath.exists(): + print(f"Error: {filepath} already exists") + sys.exit(1) + + # Write changeset + manager.changeset_dir.mkdir(exist_ok=True) + content = f"""type: {bump_type} +packages: [ {', '.join(packages)} ] +changelog: |- + {changelog} +""" + filepath.write_text(content) + print(f"\nโœ… Created {filepath.relative_to(manager.root_dir)}") + + +def cmd_status(manager: ChangesetManager): + """Show pending changesets.""" + if not manager.changeset_dir.exists(): + print("No .changeset directory found.") + return + + changesets = manager.load_changesets() + if not changesets: + print("No pending changesets.") + return + + print("Pending changesets:") + seen = set() + for cs in changesets: + if cs.file not in seen: + print(f" - {cs.file.name}") + seen.add(cs.file) + + +def cmd_version(manager: ChangesetManager): + """Apply version bumps from pending changesets.""" + changesets = manager.load_changesets() + if not changesets: + print("No pending changesets to apply.") + return + + # Determine strongest bump per module + rank = {"patch": 0, "minor": 1, "major": 2, "beta": 3} + target: Dict[str, str] = {} + + for cs in changesets: + for module in cs.modules: + old_bump = target.get(module) + if old_bump is None or rank[cs.type] > rank[old_bump]: + target[module] = cs.type + + print("\nApplying version bumps:") + bumped_modules = [] + + for module, bump in target.items(): + current = manager.read_module_version(module) + if current is None: + print(f" - {module}: NO version found (skipped)") + continue + + next_version = manager.bump_version(current, bump) + success = manager.write_module_version(module, next_version) + + if success: + print(f" - {module}: {current} โ†’ {next_version} ({bump})") + bumped_modules.append(module) + + # Update version.py for http module + if module == "http": + version_file = manager.packages_dir / "http" / "src" / "turnkey_http" / "version.py" + version_file.write_text( + f'"""Auto-generated version file. Do not edit manually."""\n\n' + f'VERSION = "turnkey/python-sdk@{next_version}"\n' + ) + else: + print(f" - {module}: failed to write version") + + # Move applied changesets to .changeset/applied/ + manager.applied_dir.mkdir(parents=True, exist_ok=True) + seen = set() + for cs in changesets: + if cs.file in seen: + continue + seen.add(cs.file) + dest = manager.applied_dir / cs.file.name + shutil.move(str(cs.file), str(dest)) + + print(f"\nMoved {len(seen)} file(s) to .changeset/applied/") + + # Write bumped modules list + bumped_list_file = manager.changeset_dir / ".last_bumped_modules" + bumped_list_file.write_text("\n".join(target.keys()) + "\n") + print(f"Wrote bumped module list to {bumped_list_file}") + + +def cmd_changelog(manager: ChangesetManager): + """Generate CHANGELOG.md entries from applied changesets.""" + if not manager.applied_dir.exists(): + print("No .changeset/applied directory; nothing to write.") + return + + applied = manager.load_changesets(from_dir=manager.applied_dir) + if not applied: + print("No applied changesets found; nothing to write.") + return + + today = date.today().isoformat() + + # Group by module + by_module: Dict[str, List[tuple[str, str]]] = {} + for cs in applied: + for module in cs.modules: + if module not in by_module: + by_module[module] = [] + by_module[module].append((cs.type, cs.summary)) + + for module, entries in by_module.items(): + new_version = manager.read_module_version(module) or "UNSPECIFIED" + changelog = manager.packages_dir / module / "CHANGELOG.md" + + # Build new section + section_lines = [f"## {new_version} โ€” {today}", ""] + + # Group by bump type + by_type: Dict[str, List[str]] = {} + for bump_type, summary in entries: + if bump_type not in by_type: + by_type[bump_type] = [] + by_type[bump_type].append(summary) + + for bump_type in ["major", "minor", "patch", "beta"]: + if bump_type in by_type: + section_lines.append(f"### {bump_type.capitalize()} Changes") + for msg in by_type[bump_type]: + section_lines.append(f"- {msg}") + section_lines.append("") + + section = "\n".join(section_lines) + + # Read existing changelog + if changelog.exists(): + existing = changelog.read_text() + else: + existing = "# Changelog\n\n" + + # Insert new section after header + if existing.startswith("# Changelog"): + split_idx = existing.find("\n\n") + if split_idx >= 0: + header = existing[:split_idx].rstrip() + rest = existing[split_idx + 2:] + else: + header = existing.rstrip() + rest = "" + else: + header = "# Changelog" + rest = "\n\n" + existing + + updated = f"{header}\n\n{section}\n{rest}" + changelog.write_text(updated) + + relative = changelog.relative_to(manager.root_dir) + print(f"Updated {relative}") + + # Clean up applied changesets + for cs in applied: + cs.file.unlink(missing_ok=True) + + if not any(manager.applied_dir.iterdir()): + manager.applied_dir.rmdir() + + print("Cleared applied changesets.") + + +def main(): + """Main entry point.""" + if len(sys.argv) < 2: + print("Usage: manage.py ") + sys.exit(1) + + command = sys.argv[1] + root_dir = Path(__file__).parent.parent + manager = ChangesetManager(root_dir) + + if command == "new": + cmd_new(manager) + elif command == "status": + cmd_status(manager) + elif command == "version": + cmd_version(manager) + elif command == "changelog": + cmd_changelog(manager) + else: + print(f"Unknown command: {command}") + print("Usage: manage.py ") + sys.exit(1) + + +if __name__ == "__main__": + main() From 859fabf867791f0c12bd5f01286ff4ac78136a57 Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Fri, 23 Jan 2026 14:50:51 -0500 Subject: [PATCH 2/2] added workflows, license, and made some pyproject changes to match our licensing --- .github/actions/setup-python/action.yml | 45 +++++ .github/workflows/python-build.yml | 37 ++++ .github/workflows/version-and-publish.yml | 196 +++++++++++++++++++++ LICENSE | 201 ++++++++++++++++++++++ Makefile | 19 +- changesets/manage.py | 121 ++++++------- packages/api-key-stamper/LICENSE | 201 ++++++++++++++++++++++ packages/api-key-stamper/pyproject.toml | 4 +- packages/http/LICENSE | 201 ++++++++++++++++++++++ packages/http/pyproject.toml | 5 +- packages/http/src/turnkey_http/version.py | 5 +- packages/sdk-types/LICENSE | 201 ++++++++++++++++++++++ packages/sdk-types/pyproject.toml | 4 +- pyproject.toml | 3 + 14 files changed, 1159 insertions(+), 84 deletions(-) create mode 100644 .github/actions/setup-python/action.yml create mode 100644 .github/workflows/python-build.yml create mode 100644 .github/workflows/version-and-publish.yml create mode 100644 LICENSE create mode 100644 packages/api-key-stamper/LICENSE create mode 100644 packages/http/LICENSE create mode 100644 packages/sdk-types/LICENSE diff --git a/.github/actions/setup-python/action.yml b/.github/actions/setup-python/action.yml new file mode 100644 index 0000000..a6a5b36 --- /dev/null +++ b/.github/actions/setup-python/action.yml @@ -0,0 +1,45 @@ +name: "Setup Python" +description: "Install Python toolchain and dependencies" + +inputs: + python-version: + description: "Python version to use" + required: false + default: "3.10" + +runs: + using: "composite" + + steps: + # https://github.com/actions/setup-python + - name: Install Python + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: ${{ inputs.python-version }} + + - name: Upgrade pip + run: python -m pip install --upgrade pip + shell: bash + + - name: Get pip cache directory + id: pip-cache-dir + run: | + echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT + shell: bash + + # https://github.com/actions/cache + - name: Setup pip cache + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: ${{ steps.pip-cache-dir.outputs.dir }} + key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install dependencies + run: | + pip install -e .[dev] + pip install -e ./packages/sdk-types[dev] + pip install -e ./packages/api-key-stamper[dev] + pip install -e ./packages/http[dev] + shell: bash diff --git a/.github/workflows/python-build.yml b/.github/workflows/python-build.yml new file mode 100644 index 0000000..41e0107 --- /dev/null +++ b/.github/workflows/python-build.yml @@ -0,0 +1,37 @@ +name: Python Build + +on: + push: + branches: + - main + pull_request: + branches: + - main + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build & Test + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10", "3.11", "3.12"] + + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Setup Python + uses: ./.github/actions/setup-python + with: + python-version: ${{ matrix.python-version }} + + - name: Check formatting + run: make format-check + + - name: Run type checking + run: make typecheck diff --git a/.github/workflows/version-and-publish.yml b/.github/workflows/version-and-publish.yml new file mode 100644 index 0000000..139fe30 --- /dev/null +++ b/.github/workflows/version-and-publish.yml @@ -0,0 +1,196 @@ +name: Version and Publish + +on: + workflow_dispatch: # allows manual invocation + push: + tags: + - "v*.*.*" # e.g. v1.2.3 + +permissions: + contents: write + id-token: write + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +jobs: + build: + name: Build + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + ref: ${{ github.event.repository.default_branch }} + + - name: Setup Python + uses: ./.github/actions/setup-python + + - name: Check for pending releases + run: | + echo "Checking for pending changesets..." + CHANGES_STATUS=$(make changeset-status 2>&1) + echo "$CHANGES_STATUS" + if echo "$CHANGES_STATUS" | grep -qi "pending"; then + echo "Changesets found, continuing" + else + echo "No unreleased changesets found, exiting" + exit 1 + fi + + - name: Check formatting + run: make format-check + + - name: Run type checking + run: make typecheck + + version-and-rebuild: + name: Version and Rebuild + runs-on: ubuntu-latest + needs: build + + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + ref: ${{ github.event.repository.default_branch }} + + - name: Setup Python + uses: ./.github/actions/setup-python + + - name: Configure Git User + run: | + git config user.name "tkhq-deploy" + git config user.email "github@turnkey.engineering" + + - name: Create and switch to release branch + run: | + git fetch origin + git checkout -B release/${{ github.ref_name }} origin/release/${{ github.ref_name }} || \ + git checkout -B release/${{ github.ref_name }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Version packages + run: | + make changeset-version + make changeset-changelog + make format-check + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Commit versioned changes + run: | + git add -A + git commit -m "chore: release packages" || echo "No changes to commit" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Push changes to release branch + run: | + git push -u origin release/${{ github.ref_name }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Build packages + run: make build + + - name: Upload release artifacts + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: release-artifacts-${{ github.ref_name }} + path: | + packages/*/dist/ + .changeset/** + retention-days: 7 + + prepare-release: + name: Prepare Release + runs-on: ubuntu-latest + needs: version-and-rebuild + + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + ref: release/${{ github.ref_name }} + + - name: Create GitHub Release + uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2 + with: + tag_name: ${{ github.ref_name }} + name: Release ${{ github.ref_name }} + generate_release_notes: true + draft: true + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + publish: + name: Publish to PyPI + needs: prepare-release + runs-on: + group: package-deploy + environment: production # require manual approval for production deployments + + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + ref: release/${{ github.ref_name }} + + - name: Download release artifacts + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: release-artifacts-${{ github.ref_name }} + path: . + + - name: Prepare packages for publishing + run: | + mkdir -p dist-to-publish + + if [ ! -f .changeset/.last_bumped_modules ]; then + echo "No .last_bumped_modules file found, nothing to publish" + exit 1 + fi + + echo "Packages to publish:" + cat .changeset/.last_bumped_modules + + while IFS= read -r module || [ -n "$module" ]; do + # Skip empty lines + [ -z "$module" ] && continue + + dist_dir="packages/${module}/dist" + if [ -d "$dist_dir" ]; then + echo "Copying ${module} artifacts..." + cp "${dist_dir}"/* dist-to-publish/ + else + echo "Warning: dist directory not found for ${module}" + fi + done < .changeset/.last_bumped_modules + + echo "Artifacts to publish:" + ls -la dist-to-publish/ + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 + with: + packages-dir: dist-to-publish/ + + - name: Success + run: | + echo -e "\033[0;32m" + echo "โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•—โ–‘โ–‘โ–‘โ–ˆโ–ˆโ•—โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–‘โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—" + echo "โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•‘โ–‘โ–‘โ–‘โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•" + echo "โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–‘โ–ˆโ–ˆโ•‘โ–‘โ–‘โ–‘โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘โ–‘โ–‘โ•šโ•โ•โ–ˆโ–ˆโ•‘โ–‘โ–‘โ•šโ•โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–‘โ–‘โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–‘โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–‘" + echo "โ–‘โ•šโ•โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘โ–‘โ–‘โ–‘โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘โ–‘โ–‘โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘โ–‘โ–‘โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ•โ–‘โ–‘โ–‘โ•šโ•โ•โ•โ–ˆโ–ˆโ•—โ–‘โ•šโ•โ•โ•โ–ˆโ–ˆโ•—" + echo "โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•" + echo "โ•šโ•โ•โ•โ•โ•โ•โ–‘โ–‘โ•šโ•โ•โ•โ•โ•โ•โ–‘โ–‘โ•šโ•โ•โ•โ•โ•โ–‘โ–‘โ•šโ•โ•โ•โ•โ•โ–‘โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ•โ–‘โ•šโ•โ•โ•โ•โ•โ•โ–‘" + echo -e "\033[0m" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..271581a --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2026 Turnkey + + 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. \ No newline at end of file diff --git a/Makefile b/Makefile index f5cbfbd..1fefb7a 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: generate generate-types generate-http test format typecheck install clean help changeset changeset-status changeset-version changeset-changelog +.PHONY: generate generate-types generate-http test format format-check typecheck install clean help changeset changeset-status changeset-version changeset-changelog build help: @echo "Available commands:" @@ -9,6 +9,7 @@ help: @echo " make format - Format all Python files with ruff" @echo " make typecheck - Run mypy type checking" @echo " make install - Install all packages in dev mode" + @echo " make build - Build all packages for distribution" @echo " make clean - Remove generated files and caches" @echo "" @echo "Changeset commands:" @@ -35,6 +36,11 @@ format: @echo "๐ŸŽจ Formatting code..." @ruff format . +format-check: + @echo "๐Ÿ” Checking code format..." + @ruff format --check . + @echo "โœ… Code format is correct" + typecheck: @echo "๐Ÿ” Running type checks..." @mypy packages/ @@ -48,6 +54,17 @@ install: @pip install -e ./packages/http[dev] @echo "โœ… All packages installed" +build: + @echo "๐Ÿ“ฆ Building packages for distribution..." + @pip install build + @for pkg in packages/*/; do \ + if [ -f "$$pkg/pyproject.toml" ]; then \ + echo "Building $$pkg..."; \ + python -m build "$$pkg"; \ + fi \ + done + @echo "โœ… All packages built" + clean: @echo "๐Ÿงน Cleaning up..." @find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true diff --git a/changesets/manage.py b/changesets/manage.py index 4212a3a..04c159c 100755 --- a/changesets/manage.py +++ b/changesets/manage.py @@ -4,7 +4,7 @@ import re import sys from dataclasses import dataclass -from datetime import date +from datetime import date, datetime from pathlib import Path from typing import List, Dict, Optional import shutil @@ -13,6 +13,7 @@ @dataclass class Changeset: """Represents a changeset file with modules, type, and summary.""" + file: Path modules: List[str] # e.g., ["api-key-stamper", "http", "sdk-types"] type: str # patch | minor | major | beta @@ -35,7 +36,8 @@ def load_changesets(self, from_dir: Optional[Path] = None) -> List[Changeset]: return [] files = sorted( - f for f in target_dir.iterdir() + f + for f in target_dir.iterdir() if f.is_file() and f.suffix in {".yml", ".yaml", ".md"} ) @@ -50,80 +52,43 @@ def _parse_changeset(self, file: Path) -> List[Changeset]: """Parse a changeset file (YAML or Markdown front-matter).""" text = file.read_text() - # Try YAML array form first + # YAML array form: # type: minor # packages: [ api-key-stamper, http ] # changelog: |- # summary... - type_match = re.search(r'(?mi)^\s*type\s*:\s*"?(major|minor|patch|beta)"?\s*$', text) - array_match = re.search(r'(?ms)^\s*packages\s*:\s*\[(.*?)\]\s*$', text) - - if array_match: - packages = [ - p.strip().strip('"\'') - for p in array_match.group(1).split(',') - if p.strip() - ] - if packages: - bump_type = type_match.group(1).lower() if type_match else "patch" - summary = self._extract_changelog(text) - return [Changeset(file, packages, bump_type, summary)] - - # Try YAML mapping form - # packages: - # api-key-stamper: minor - # http: patch - mapping_match = re.search(r'(?ms)^\s*packages\s*:\s*\n(.*?)(^\S|\Z)', text) - if mapping_match: - entries = [] - for line in mapping_match.group(1).splitlines(): - entry_match = re.match(r'^\s+(.+?)\s*:\s*(major|minor|patch|beta)\s*$', line) - if entry_match: - entries.append((entry_match.group(1).strip(), entry_match.group(2).strip())) - - if entries: - summary = self._extract_changelog(text) - return [ - Changeset(file, [mod], bump, summary) - for mod, bump in entries - ] - - # Try Markdown front-matter - # --- - # type: minor - # packages: - # - api-key-stamper - # - http - # --- - # body... - fm_match = re.match(r'(?s)^---\s*(.*?)\s*---\s*(.*)$', text) - if fm_match: - front, body = fm_match.groups() - - type_fm = re.search(r'(?mi)^\s*type\s*:\s*"?(major|minor|patch|beta)"?\s*$', front) - packages_fm = re.findall(r'(?m)^\s*-\s*(.+)\s*$', front) - - if packages_fm: - bump_type = type_fm.group(1).lower() if type_fm else "patch" - return [Changeset(file, packages_fm, bump_type, body.strip())] + type_match = re.search( + r'(?mi)^\s*type\s*:\s*"?(major|minor|patch|beta)"?\s*$', text + ) + array_match = re.search(r"(?ms)^\s*packages\s*:\s*\[(.*?)\]\s*$", text) - return [] + packages = [ + p.strip().strip("\"'") for p in array_match.group(1).split(",") if p.strip() + ] + if packages: + bump_type = type_match.group(1).lower() if type_match else "patch" + summary = self._extract_changelog(text) + return [Changeset(file, packages, bump_type, summary)] def _extract_changelog(self, text: str) -> str: """Extract changelog content from YAML.""" - match = re.search(r'(?ms)^\s*changelog\s*:\s*\|-\s*\n(.*)$', text) + match = re.search(r"(?ms)^\s*changelog\s*:\s*\|-\s*\n(.*)$", text) if not match: return "" body = match.group(1) - return '\n'.join(line.removeprefix(" ") for line in body.splitlines()).strip() + return "\n".join(line.removeprefix(" ") for line in body.splitlines()).strip() def bump_version(self, version: str, bump: str) -> str: """Bump a semantic version string.""" - match = re.match(r'^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z\.-]+))?$', version) + match = re.match(r"^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z\.-]+))?$", version) if not match: return version - major, minor, patch = int(match.group(1)), int(match.group(2)), int(match.group(3)) + major, minor, patch = ( + int(match.group(1)), + int(match.group(2)), + int(match.group(3)), + ) pre = match.group(4) or "" bump = bump.lower() @@ -169,7 +134,9 @@ def write_module_version(self, module_name: str, new_version: str) -> bool: pattern = r'(^\s*version\s*=\s*["\'])([^"\']+)(["\'])' if re.search(pattern, text, re.MULTILINE): - updated = re.sub(pattern, rf'\g<1>{new_version}\g<3>', text, flags=re.MULTILINE) + updated = re.sub( + pattern, rf"\g<1>{new_version}\g<3>", text, flags=re.MULTILINE + ) pyproject.write_text(updated) return True @@ -187,15 +154,19 @@ def cmd_new(manager: ChangesetManager): print(" 3) major - Breaking changes") print(" 4) beta - Pre-release") choice = input("\nSelect type [1-4]: ").strip() - + type_map = {"1": "patch", "2": "minor", "3": "major", "4": "beta"} bump_type = type_map.get(choice, "patch") # Get packages - packages_list = [p.name for p in manager.packages_dir.iterdir() if p.is_dir() and not p.name.startswith('.')] + packages_list = [ + p.name + for p in manager.packages_dir.iterdir() + if p.is_dir() and not p.name.startswith(".") + ] print(f"\nAvailable packages: {', '.join(packages_list)}") packages_input = input("Packages (comma-separated): ").strip() - packages = [p.strip() for p in packages_input.split(',') if p.strip()] + packages = [p.strip() for p in packages_input.split(",") if p.strip()] if not packages: print("Error: At least one package is required") @@ -210,16 +181,14 @@ def cmd_new(manager: ChangesetManager): lines.append(line) except EOFError: pass - - changelog = '\n'.join(lines).strip() + + changelog = "\n".join(lines).strip() if not changelog: changelog = "No description provided" # Generate filename - name = input("\nChangeset filename (without extension): ").strip() - if not name: - name = f"change-{date.today().strftime('%Y%m%d')}" - + name = f"change-{datetime.now().strftime('%Y%m%d-%H:%M:%S')}" + filepath = manager.changeset_dir / f"{name}.yml" if filepath.exists(): print(f"Error: {filepath} already exists") @@ -228,7 +197,7 @@ def cmd_new(manager: ChangesetManager): # Write changeset manager.changeset_dir.mkdir(exist_ok=True) content = f"""type: {bump_type} -packages: [ {', '.join(packages)} ] +packages: [ {", ".join(packages)} ] changelog: |- {changelog} """ @@ -290,10 +259,16 @@ def cmd_version(manager: ChangesetManager): # Update version.py for http module if module == "http": - version_file = manager.packages_dir / "http" / "src" / "turnkey_http" / "version.py" + version_file = ( + manager.packages_dir + / "http" + / "src" + / "turnkey_http" + / "version.py" + ) version_file.write_text( f'"""Auto-generated version file. Do not edit manually."""\n\n' - f'VERSION = "turnkey/python-sdk@{next_version}"\n' + f'VERSION = "turnkey-python-http@{next_version}"\n' ) else: print(f" - {module}: failed to write version") @@ -371,7 +346,7 @@ def cmd_changelog(manager: ChangesetManager): split_idx = existing.find("\n\n") if split_idx >= 0: header = existing[:split_idx].rstrip() - rest = existing[split_idx + 2:] + rest = existing[split_idx + 2 :] else: header = existing.rstrip() rest = "" diff --git a/packages/api-key-stamper/LICENSE b/packages/api-key-stamper/LICENSE new file mode 100644 index 0000000..271581a --- /dev/null +++ b/packages/api-key-stamper/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2026 Turnkey + + 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. \ No newline at end of file diff --git a/packages/api-key-stamper/pyproject.toml b/packages/api-key-stamper/pyproject.toml index 128d863..9869d44 100644 --- a/packages/api-key-stamper/pyproject.toml +++ b/packages/api-key-stamper/pyproject.toml @@ -8,7 +8,8 @@ version = "0.1.0" description = "API key authentication stamper for Turnkey API" readme = "README.md" requires-python = ">=3.8" -license = {text = "MIT"} +license = "Apache-2.0" +license-files = ["LICENSE"] authors = [ {name = "Turnkey", email = "hello@turnkey.com"} ] @@ -16,7 +17,6 @@ keywords = ["turnkey", "api", "authentication", "stamper"] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", diff --git a/packages/http/LICENSE b/packages/http/LICENSE new file mode 100644 index 0000000..271581a --- /dev/null +++ b/packages/http/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2026 Turnkey + + 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. \ No newline at end of file diff --git a/packages/http/pyproject.toml b/packages/http/pyproject.toml index a6d0a3c..19293a9 100644 --- a/packages/http/pyproject.toml +++ b/packages/http/pyproject.toml @@ -8,15 +8,14 @@ version = "0.1.0" description = "HTTP client for Turnkey API" readme = "README.md" requires-python = ">=3.8" -license = {text = "MIT"} +license = "Apache-2.0" +license-files = ["LICENSE"] authors = [ {name = "Turnkey", email = "hello@turnkey.com"} ] keywords = ["turnkey", "api", "http", "client", "sdk"] classifiers = [ - "Development Status :: 3 - Alpha", "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", diff --git a/packages/http/src/turnkey_http/version.py b/packages/http/src/turnkey_http/version.py index 6d61cdf..9f8ca6a 100644 --- a/packages/http/src/turnkey_http/version.py +++ b/packages/http/src/turnkey_http/version.py @@ -1,4 +1,3 @@ -"""Package version for Turnkey HTTP client.""" +"""Auto-generated version file. Do not edit manually.""" -# Version is updated automatically during publish -VERSION = "turnkey-http@0.1.0" +VERSION = "turnkey-python-http@0.1.0" diff --git a/packages/sdk-types/LICENSE b/packages/sdk-types/LICENSE new file mode 100644 index 0000000..271581a --- /dev/null +++ b/packages/sdk-types/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2026 Turnkey + + 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. \ No newline at end of file diff --git a/packages/sdk-types/pyproject.toml b/packages/sdk-types/pyproject.toml index 1018c93..e716748 100644 --- a/packages/sdk-types/pyproject.toml +++ b/packages/sdk-types/pyproject.toml @@ -8,7 +8,8 @@ version = "0.1.0" description = "Type definitions for Turnkey API" readme = "README.md" requires-python = ">=3.8" -license = {text = "MIT"} +license = "Apache-2.0" +license-files = ["LICENSE"] authors = [ {name = "Turnkey", email = "hello@turnkey.com"} ] @@ -16,7 +17,6 @@ keywords = ["turnkey", "api", "types", "sdk"] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", diff --git a/pyproject.toml b/pyproject.toml index ce29e81..7dbc563 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,3 +37,6 @@ exclude = [ "^dist/", "^\\.eggs/", ] + +[tool.setuptools.packages.find] +exclude = ["schema*", "codegen*", "changesets*"]