Skip to content

Commit 570c4e2

Browse files
authored
[feat] python client (#22)
Add a python client library
1 parent 741056a commit 570c4e2

35 files changed

+4624
-185
lines changed

.github/copilot-instructions.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ Use the same output file name (test_output.log) every time so that you don't lit
132132
### Errors
133133
- go errors should be tested with errors.Is(). String matching is only okay for external system errors.
134134

135+
## Backawards compatibility
136+
137+
There are no current users of this library. No users of the production server.
138+
Breaking changes are allowed.
139+
135140
## Key Principles
136141

137142
1. **Real cloud provider functionality is the only thing that matters**

.github/workflows/cloud_provider.yml

Lines changed: 102 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,39 @@ jobs:
1616

1717
strategy:
1818
matrix:
19-
# Aside from general setup of dot files and such, which
20-
# a personal preference, the following should be done.
21-
# Assuming ubuntu.
19+
# Self-hosted runner setup for cloud provider testing.
20+
# Assuming Ubuntu environment on AWS EC2, GCP Compute Engine, or Azure VM.
2221
#
22+
# Base system setup:
2323
# sudo apt update
2424
# sudo snap install go --classic
25+
# sudo apt install -y python3 python3-pip python3-venv
26+
# sudo apt install -y python3-aiohttp python3-boto3 python3-google-auth python3-jwt python3-cryptography
27+
# sudo apt install -y python3-pytest python3-pytest-cov python3-pytest-asyncio python3-requests
28+
# sudo apt install -y python3-azure-identity python3-google-auth-oauthlib
2529
#
26-
# AWS:
30+
# AWS EC2 setup:
2731
# sudo snap install aws-cli --classic
32+
# Ensure EC2 instance has IAM role attached for AWS credential access
2833
#
29-
# Azure:
34+
# GCP Compute Engine setup:
35+
# Ensure VM has service account attached with appropriate permissions
36+
# GCP credentials are automatically available via metadata service
37+
#
38+
# Azure VM setup:
3039
# curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
31-
# az vm identity assign --name $identity --resource-group $resource_group
40+
# az vm identity assign --name $vm_name --resource-group $resource_group
41+
# Ensure VM has managed identity enabled for Azure credential access
3242
#
33-
# Environment Variables:
43+
# Environment Variables for testing:
3444
# S2IAM_TEST_ASSUME_ROLE - Set to a role ARN/identifier to test role assumption (AWS/GCP only)
35-
# S2IAM_TEST_CLOUD_PROVIDER - Set to indicate cloud tests should run (for providers without role assumption like Azure)
45+
# S2IAM_TEST_CLOUD_PROVIDER - Set to indicate cloud tests should run (aws/gcp/azure)
46+
# S2IAM_DEBUGGING - Set to true for verbose test output
47+
#
48+
# Both Go and Python testing are fully automated via GitHub Actions
49+
# Go: Runs integration tests with coverage reporting (go coverage format)
50+
# Python: Uses automated validation framework with coverage reporting (XML format)
51+
# Coverage from all environments (no CSP, AWS, Azure, GCP) is uploaded to Codecov
3652
#
3753
include:
3854
- name: aws-positive
@@ -94,7 +110,7 @@ jobs:
94110
"${{ env.TEST_USERNAME }}@${{ env.TEST_HOSTNAME }}" \
95111
"mkdir -p tests/${{ env.UNIQUE_DIR }} && cd tests/${{ env.UNIQUE_DIR }} && tar xzf -"
96112
97-
- name: Run tests with coverage and verification
113+
- name: Run Go tests with coverage and verification
98114
run: |
99115
ssh -i ~/.ssh/key -o StrictHostKeyChecking=no ${{ env.TEST_USERNAME }}@${{ env.TEST_HOSTNAME }} << 'EOF' 2>&1 | tee test_output.log
100116
set -ex
@@ -106,9 +122,39 @@ jobs:
106122
107123
ls -la coverage.out
108124
EOF
125+
126+
- name: Run Python tests with coverage
127+
run: |
128+
ssh -i ~/.ssh/key -o StrictHostKeyChecking=no ${{ env.TEST_USERNAME }}@${{ env.TEST_HOSTNAME }} << 'EOF' 2>&1 | tee python_test_output.log
129+
set -ex
130+
cd tests/${{ env.UNIQUE_DIR }}/python
131+
132+
# Install Python 3 and dependencies if not available
133+
if ! command -v python3 &> /dev/null; then
134+
sudo apt update
135+
sudo apt install -y python3 python3-pip python3-venv
136+
fi
137+
138+
# Install Python dependencies for s2iam library
139+
sudo apt install -y python3-aiohttp python3-boto3 python3-google-auth python3-jwt python3-cryptography python3-pytest python3-pytest-cov python3-pytest-asyncio python3-requests python3-azure-identity python3-google-auth-oauthlib || true
140+
141+
# Run Python tests with coverage using our automated validation framework
142+
env USE_SYSTEM_PACKAGES=1 ${{ env.EXTRA_ENV }} S2IAM_DEBUGGING=true ./tests/run_cloud_validation.sh --coverage
143+
144+
# Verify test completion
145+
echo "Checking for test completion marker..."
146+
if [ ! -f "coverage.xml" ]; then
147+
echo "ERROR: Coverage file not generated - tests may have failed"
148+
exit 1
149+
fi
150+
151+
# Verify coverage file was generated
152+
ls -la coverage.xml
153+
EOF
109154
110155
- name: Verify test results
111156
run: |
157+
echo "=== Verifying Go test results ==="
112158
echo "Checking for TestWithDebugging..."
113159
grep --silent -- "--- PASS: TestWithDebugging" test_output.log
114160
echo "Checking for PASS..."
@@ -123,9 +169,16 @@ jobs:
123169
grep --silent "^ok github.com/singlestore-labs/singlestore-auth-iam/go/cmd/s2iam_test_server " test_output.log
124170
echo "Checking s2iam package pattern..."
125171
grep --silent "^ok github.com/singlestore-labs/singlestore-auth-iam/go/s2iam " test_output.log
172+
echo "Go tests passed successfully!"
173+
174+
echo "=== Verifying Python test results ==="
175+
echo "Checking for Python test completion..."
176+
grep --silent "Test run completed successfully!" python_test_output.log
177+
echo "Python tests passed successfully!"
178+
126179
echo "All tests passed successfully!"
127180
128-
- name: Download coverage file
181+
- name: Download Go coverage file
129182
run: |
130183
# Verify coverage file exists on remote
131184
ssh -i ~/.ssh/key -o StrictHostKeyChecking=no \
@@ -134,24 +187,53 @@ jobs:
134187
135188
# Download coverage file from remote
136189
scp -i ~/.ssh/key -o StrictHostKeyChecking=no \
137-
${{ env.TEST_USERNAME }}@${{ env.TEST_HOSTNAME }}:tests/${{ env.UNIQUE_DIR }}/go/coverage.out ./coverage.out
190+
${{ env.TEST_USERNAME }}@${{ env.TEST_HOSTNAME }}:tests/${{ env.UNIQUE_DIR }}/go/coverage.out ./go-coverage.out
138191
139192
# Verify local coverage file
140-
echo "Local coverage file: $(ls -la coverage.out)"
193+
echo "Local Go coverage file: $(ls -la go-coverage.out)"
194+
195+
- name: Download Python coverage file
196+
run: |
197+
# Verify Python coverage file exists on remote
198+
ssh -i ~/.ssh/key -o StrictHostKeyChecking=no \
199+
${{ env.TEST_USERNAME }}@${{ env.TEST_HOSTNAME }} \
200+
"ls -la tests/${{ env.UNIQUE_DIR }}/python/coverage.xml"
201+
202+
# Download Python coverage file from remote
203+
scp -i ~/.ssh/key -o StrictHostKeyChecking=no \
204+
${{ env.TEST_USERNAME }}@${{ env.TEST_HOSTNAME }}:tests/${{ env.UNIQUE_DIR }}/python/coverage.xml ./python-coverage.xml
205+
206+
# Verify local Python coverage file
207+
echo "Local Python coverage file: $(ls -la python-coverage.xml)"
141208
142-
- name: Display coverage
209+
- name: Display Go coverage
143210
run: |
211+
echo "=== Go Coverage ==="
144212
echo "Original coverage file paths:"
145-
(grep azure coverage.out | head) || echo no azure in coverage
146-
head -2 coverage.out
147-
148-
- name: Upload coverage to Codecov
213+
(grep azure go-coverage.out | head) || echo no azure in go coverage
214+
head -2 go-coverage.out
215+
echo ""
216+
echo "=== Python Coverage ==="
217+
echo "Python coverage summary:"
218+
head -10 python-coverage.xml
219+
220+
- name: Upload Go coverage to Codecov
221+
uses: codecov/[email protected]
222+
with:
223+
fail_ci_if_error: true
224+
name: ${{ matrix.name }}-go-coverage
225+
file: ./go-coverage.out
226+
flags: go,${{ matrix.name }}
227+
env:
228+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
229+
230+
- name: Upload Python coverage to Codecov
149231
uses: codecov/[email protected]
150232
with:
151233
fail_ci_if_error: true
152-
name: ${{ matrix.name }}-coverage
153-
file: ./coverage.out
154-
flags: ${{ matrix.name }}
234+
name: ${{ matrix.name }}-python-coverage
235+
file: ./python-coverage.xml
236+
flags: python,${{ matrix.name }}
155237
env:
156238
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
157239

.github/workflows/python.yml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: Python s2iam Tests
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ "**" ]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
test:
14+
runs-on: ubuntu-latest
15+
strategy:
16+
matrix:
17+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
18+
19+
steps:
20+
- name: Checkout repository
21+
uses: actions/checkout@v4
22+
23+
- name: Set up Python ${{ matrix.python-version }}
24+
uses: actions/setup-python@v4
25+
with:
26+
python-version: ${{ matrix.python-version }}
27+
28+
- name: Set up Go
29+
uses: actions/setup-go@v4
30+
with:
31+
go-version: '1.21'
32+
33+
- name: Install Python dependencies
34+
working-directory: ./python
35+
run: |
36+
python -m pip install --upgrade pip
37+
pip install -e '.[dev]'
38+
39+
- name: Run linting and type checking
40+
working-directory: ./python
41+
run: |
42+
flake8 --max-line-length=120 src tests
43+
black --check src tests
44+
isort --check-only src tests
45+
mypy src
46+
47+
- name: Run tests with coverage
48+
working-directory: ./python
49+
run: |
50+
# Run the same validation script as cloud provider tests
51+
./tests/run_cloud_validation.sh --coverage
52+
53+
- name: Upload coverage to Codecov
54+
if: matrix.python-version == '3.11'
55+
uses: codecov/[email protected]
56+
with:
57+
file: ./python/coverage.xml
58+
flags: python
59+
name: python-coverage
60+
fail_ci_if_error: false
61+
env:
62+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
63+
64+
- name: Upload coverage artifacts
65+
if: matrix.python-version == '3.11'
66+
uses: actions/upload-artifact@v4
67+
with:
68+
name: python-coverage-report
69+
path: |
70+
python/htmlcov/
71+
python/coverage.xml

0 commit comments

Comments
 (0)