pycarlo 0.0.2__tar.gz → 0.12.64__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pycarlo might be problematic. Click here for more details.

Files changed (119) hide show
  1. pycarlo-0.12.64/.circleci/config.yml +110 -0
  2. pycarlo-0.12.64/.circleci/scripts/clean-generated-types-prs.sh +171 -0
  3. pycarlo-0.12.64/.coveragerc +2 -0
  4. pycarlo-0.12.64/.github/workflows/release.yml +66 -0
  5. pycarlo-0.12.64/.gitignore +140 -0
  6. pycarlo-0.12.64/.pre-commit-config.yaml +31 -0
  7. pycarlo-0.12.64/CONTRIBUTING.md +47 -0
  8. pycarlo-0.12.64/Makefile +135 -0
  9. pycarlo-0.12.64/PKG-INFO +303 -0
  10. pycarlo-0.12.64/README.md +276 -0
  11. pycarlo-0.12.64/examples/sample_circuit_breaker.py +11 -0
  12. pycarlo-0.12.64/examples/sample_insight_upload.py +39 -0
  13. {pycarlo-0.0.2 → pycarlo-0.12.64}/pycarlo/common/__init__.py +14 -2
  14. pycarlo-0.12.64/pycarlo/common/errors.py +31 -0
  15. pycarlo-0.12.64/pycarlo/common/files.py +78 -0
  16. pycarlo-0.12.64/pycarlo/common/http.py +36 -0
  17. pycarlo-0.12.64/pycarlo/common/mcon.py +26 -0
  18. pycarlo-0.12.64/pycarlo/common/retries.py +129 -0
  19. pycarlo-0.12.64/pycarlo/common/settings.py +89 -0
  20. pycarlo-0.12.64/pycarlo/common/utils.py +51 -0
  21. pycarlo-0.12.64/pycarlo/core/__init__.py +10 -0
  22. pycarlo-0.12.64/pycarlo/core/client.py +267 -0
  23. pycarlo-0.12.64/pycarlo/core/endpoint.py +289 -0
  24. {pycarlo-0.0.2 → pycarlo-0.12.64}/pycarlo/core/operations.py +4 -2
  25. pycarlo-0.12.64/pycarlo/core/session.py +127 -0
  26. {pycarlo-0.0.2 → pycarlo-0.12.64}/pycarlo/features/__init__.py +2 -2
  27. pycarlo-0.12.64/pycarlo/features/circuit_breakers/__init__.py +3 -0
  28. pycarlo-0.12.64/pycarlo/features/circuit_breakers/exceptions.py +10 -0
  29. pycarlo-0.12.64/pycarlo/features/circuit_breakers/service.py +346 -0
  30. pycarlo-0.12.64/pycarlo/features/dbt/__init__.py +3 -0
  31. pycarlo-0.12.64/pycarlo/features/dbt/dbt_importer.py +208 -0
  32. pycarlo-0.12.64/pycarlo/features/dbt/queries.py +31 -0
  33. pycarlo-0.12.64/pycarlo/features/exceptions.py +18 -0
  34. pycarlo-0.12.64/pycarlo/features/metadata/__init__.py +32 -0
  35. pycarlo-0.12.64/pycarlo/features/metadata/asset_allow_block_list.py +22 -0
  36. pycarlo-0.12.64/pycarlo/features/metadata/asset_filters_container.py +79 -0
  37. pycarlo-0.12.64/pycarlo/features/metadata/base_allow_block_list.py +137 -0
  38. pycarlo-0.12.64/pycarlo/features/metadata/metadata_allow_block_list.py +94 -0
  39. pycarlo-0.12.64/pycarlo/features/metadata/metadata_filters_container.py +262 -0
  40. pycarlo-0.12.64/pycarlo/features/pii/__init__.py +5 -0
  41. pycarlo-0.12.64/pycarlo/features/pii/constants.py +3 -0
  42. pycarlo-0.12.64/pycarlo/features/pii/pii_filterer.py +179 -0
  43. pycarlo-0.12.64/pycarlo/features/pii/queries.py +20 -0
  44. pycarlo-0.12.64/pycarlo/features/pii/service.py +56 -0
  45. pycarlo-0.12.64/pycarlo/features/user/__init__.py +4 -0
  46. pycarlo-0.12.64/pycarlo/features/user/exceptions.py +10 -0
  47. pycarlo-0.12.64/pycarlo/features/user/models.py +9 -0
  48. pycarlo-0.12.64/pycarlo/features/user/queries.py +13 -0
  49. pycarlo-0.12.64/pycarlo/features/user/service.py +71 -0
  50. pycarlo-0.12.64/pycarlo/lib/README.md +35 -0
  51. pycarlo-0.12.64/pycarlo/lib/__init__.py +0 -0
  52. pycarlo-0.12.64/pycarlo/lib/schema.json +215499 -0
  53. pycarlo-0.12.64/pycarlo/lib/schema.py +84305 -0
  54. pycarlo-0.12.64/pycarlo/lib/types.py +68 -0
  55. pycarlo-0.12.64/pycarlo.egg-info/PKG-INFO +303 -0
  56. pycarlo-0.12.64/pycarlo.egg-info/SOURCES.txt +106 -0
  57. pycarlo-0.12.64/pycarlo.egg-info/requires.txt +5 -0
  58. pycarlo-0.12.64/pyproject.toml +40 -0
  59. pycarlo-0.12.64/requirements-ci.txt +4 -0
  60. pycarlo-0.12.64/requirements-dev.txt +6 -0
  61. pycarlo-0.12.64/requirements.txt +5 -0
  62. pycarlo-0.12.64/setup.py +44 -0
  63. pycarlo-0.12.64/tests/__init__.py +0 -0
  64. pycarlo-0.12.64/tests/common/__init__.py +0 -0
  65. pycarlo-0.12.64/tests/common/data.json +3 -0
  66. pycarlo-0.12.64/tests/common/test_files.py +28 -0
  67. pycarlo-0.12.64/tests/common/test_http.py +48 -0
  68. pycarlo-0.12.64/tests/common/test_mcon.py +34 -0
  69. pycarlo-0.12.64/tests/common/test_retries.py +134 -0
  70. pycarlo-0.12.64/tests/common/test_utils.py +8 -0
  71. pycarlo-0.12.64/tests/data/README.md +17 -0
  72. pycarlo-0.12.64/tests/data/schema_original.py +84304 -0
  73. pycarlo-0.12.64/tests/features/__init__.py +0 -0
  74. pycarlo-0.12.64/tests/features/circuit_breakers/__init__.py +0 -0
  75. pycarlo-0.12.64/tests/features/circuit_breakers/test_service.py +251 -0
  76. pycarlo-0.12.64/tests/features/dbt/__init__.py +0 -0
  77. pycarlo-0.12.64/tests/features/dbt/sample_logs.txt +1 -0
  78. pycarlo-0.12.64/tests/features/dbt/sample_manifest.json +311 -0
  79. pycarlo-0.12.64/tests/features/dbt/sample_run_results.json +117 -0
  80. pycarlo-0.12.64/tests/features/dbt/test_dbt_importer.py +188 -0
  81. pycarlo-0.12.64/tests/features/metadata/test_asset_filtering.py +416 -0
  82. pycarlo-0.12.64/tests/features/metadata/test_dataset_filtering.py +708 -0
  83. pycarlo-0.12.64/tests/features/pii/sample_events/sample_md_events_01.json +152 -0
  84. pycarlo-0.12.64/tests/features/pii/sample_events/sample_md_events_02.json +17 -0
  85. pycarlo-0.12.64/tests/features/pii/test_pii_filtering.py +273 -0
  86. pycarlo-0.12.64/tests/features/user/__init__.py +0 -0
  87. pycarlo-0.12.64/tests/features/user/test_user_service.py +119 -0
  88. pycarlo-0.12.64/tests/lib/test_enum.py +166 -0
  89. pycarlo-0.12.64/tests/lib/test_enum_integration.py +88 -0
  90. pycarlo-0.12.64/tests/lib/test_schema_generation.py +182 -0
  91. pycarlo-0.12.64/tests/test_client.py +530 -0
  92. pycarlo-0.12.64/tests/test_forgiving_enums_published.sh +148 -0
  93. pycarlo-0.12.64/tests/test_operations.py +27 -0
  94. pycarlo-0.12.64/tests/test_retry_decorator.py +97 -0
  95. pycarlo-0.12.64/tests/test_session.py +109 -0
  96. pycarlo-0.12.64/tests/verify_forgiving_enums_published.py +285 -0
  97. pycarlo-0.12.64/utils/env.sh +23 -0
  98. pycarlo-0.12.64/utils/generate.py +24 -0
  99. pycarlo-0.12.64/utils/sample.env +3 -0
  100. pycarlo-0.12.64/utils/sanity.py +110 -0
  101. pycarlo-0.12.64/utils/vars.py +41 -0
  102. pycarlo-0.0.2/PKG-INFO +0 -189
  103. pycarlo-0.0.2/README.md +0 -166
  104. pycarlo-0.0.2/pycarlo/common/errors.py +0 -10
  105. pycarlo-0.0.2/pycarlo/common/settings.py +0 -45
  106. pycarlo-0.0.2/pycarlo/core/__init__.py +0 -3
  107. pycarlo-0.0.2/pycarlo/core/client.py +0 -85
  108. pycarlo-0.0.2/pycarlo/core/session.py +0 -82
  109. pycarlo-0.0.2/pycarlo/lib/schema.py +0 -10467
  110. pycarlo-0.0.2/pycarlo.egg-info/PKG-INFO +0 -189
  111. pycarlo-0.0.2/pycarlo.egg-info/SOURCES.txt +0 -20
  112. pycarlo-0.0.2/pycarlo.egg-info/requires.txt +0 -3
  113. pycarlo-0.0.2/setup.py +0 -44
  114. /pycarlo-0.0.2/pycarlo/__init__.py → /pycarlo-0.12.64/.circleci/README.md +0 -0
  115. {pycarlo-0.0.2 → pycarlo-0.12.64}/LICENSE +0 -0
  116. {pycarlo-0.0.2/pycarlo/lib → pycarlo-0.12.64/pycarlo}/__init__.py +0 -0
  117. {pycarlo-0.0.2 → pycarlo-0.12.64}/pycarlo.egg-info/dependency_links.txt +0 -0
  118. {pycarlo-0.0.2 → pycarlo-0.12.64}/pycarlo.egg-info/top_level.txt +0 -0
  119. {pycarlo-0.0.2 → pycarlo-0.12.64}/setup.cfg +0 -0
@@ -0,0 +1,110 @@
1
+ version: 2.1
2
+
3
+ deploy_filter:
4
+ &deploy_filter # YAML reference for tag based filtering on deployments
5
+ filters:
6
+ tags:
7
+ only: /^v.*/
8
+ branches:
9
+ ignore: /.*/
10
+
11
+ test_steps: &test_steps
12
+ steps:
13
+ - checkout
14
+ - run:
15
+ name: Update pip
16
+ command: pip install --upgrade pip
17
+ - run:
18
+ name: Run tests and checks
19
+ command: |
20
+ make install
21
+ make test
22
+
23
+ sanity_check: &sanity_check_steps
24
+ steps:
25
+ - checkout
26
+ - run:
27
+ name: Make Sanity Check
28
+ command: |
29
+ make install
30
+ echo "MCD_API_ENDPOINT=https://api.getmontecarlo.com/graphql" > utils/.env
31
+ echo "MCD_DEFAULT_API_ID=${MCD_DEFAULT_API_ID}" >> utils/.env
32
+ echo "MCD_DEFAULT_API_TOKEN=${MCD_DEFAULT_API_TOKEN}" >> utils/.env
33
+ make sanity-check
34
+
35
+ jobs:
36
+ run-test-3-8:
37
+ docker:
38
+ - image: python:3.8
39
+ <<: *test_steps
40
+
41
+ run-test-3-9:
42
+ docker:
43
+ - image: python:3.9
44
+ <<: *test_steps
45
+
46
+ run-test-3-10:
47
+ docker:
48
+ - image: python:3.10
49
+ <<: *test_steps
50
+
51
+ run-test-3-11:
52
+ docker:
53
+ - image: python:3.11
54
+ <<: *test_steps
55
+
56
+ run-test-3-12:
57
+ docker:
58
+ - image: python:3.12
59
+ <<: *test_steps
60
+
61
+ run-sanity-check:
62
+ docker:
63
+ - image: python:3.9
64
+ <<: *sanity_check_steps
65
+
66
+ deploy: # cci-ignore
67
+ docker:
68
+ - image: python:3.8.6
69
+
70
+ steps:
71
+ - checkout
72
+ - run:
73
+ name: Deploy to PyPI
74
+ command: make distribute
75
+
76
+ workflows:
77
+ build:
78
+ jobs:
79
+ - run-test-3-8
80
+ - run-test-3-9
81
+ - run-test-3-10
82
+ - run-test-3-11
83
+ - run-test-3-12
84
+ - run-sanity-check:
85
+ context: mc-prod # cci-ignore
86
+
87
+ deploy: # cci-ignore
88
+ jobs:
89
+ - run-test-3-8:
90
+ <<: *deploy_filter
91
+ - run-test-3-9:
92
+ <<: *deploy_filter
93
+ - run-test-3-10:
94
+ <<: *deploy_filter
95
+ - run-test-3-11:
96
+ <<: *deploy_filter
97
+ - run-test-3-12:
98
+ <<: *deploy_filter
99
+ - run-sanity-check:
100
+ context: mc-prod # cci-ignore
101
+ <<: *deploy_filter
102
+ - deploy:
103
+ requires:
104
+ - run-test-3-8
105
+ - run-test-3-9
106
+ - run-test-3-10
107
+ - run-test-3-11
108
+ - run-test-3-12
109
+ - run-sanity-check
110
+ <<: *deploy_filter
@@ -0,0 +1,171 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ # Colors for output
5
+ RED='\033[1;31m'
6
+ GREEN='\033[1;32m'
7
+ YELLOW='\033[1;33m'
8
+ BLUE='\033[0;36m' # Light cyan/blue
9
+ NC='\033[0m' # No Color
10
+
11
+ # Print functions
12
+ info() {
13
+ echo -e "${BLUE}$1${NC}" >&2
14
+ }
15
+
16
+ success() {
17
+ echo -e "${GREEN}$1${NC}" >&2
18
+ }
19
+
20
+ warn() {
21
+ echo -e "${YELLOW}[WARNING]${NC} $1" >&2
22
+ }
23
+
24
+ error() {
25
+ echo -e "${RED}[ERROR]${NC} $1" >&2
26
+ }
27
+
28
+ # Function to trigger type generation workflow for a given monolith PR
29
+ rerun_generation() {
30
+ local monolith_pr=$1
31
+ info "Triggering type generation workflow for monolith PR #$monolith_pr..."
32
+
33
+ # Get the branch name for the monolith PR
34
+ local monolith_branch
35
+ monolith_branch=$(gh pr view "$monolith_pr" --repo monte-carlo-data/monolith-django --json headRefName --jq '.headRefName' 2>/dev/null)
36
+
37
+ if [ -z "$monolith_branch" ]; then
38
+ error "Failed to get branch name for monolith PR #$monolith_pr"
39
+ return 1
40
+ fi
41
+
42
+ info "Found monolith branch: $monolith_branch"
43
+
44
+ # Get the latest workflow run for this branch
45
+ local run_id
46
+ run_id=$(gh run list --repo monte-carlo-data/monolith-django \
47
+ --workflow handle-pycarlo-schema-changes.yml \
48
+ --branch "$monolith_branch" \
49
+ --limit 1 \
50
+ --json databaseId \
51
+ --jq '.[0].databaseId' 2>/dev/null)
52
+
53
+ if [ -z "$run_id" ]; then
54
+ error "No workflow runs found for monolith PR #$monolith_pr (branch: $monolith_branch)"
55
+ return 1
56
+ fi
57
+
58
+ info "Found workflow run ID: $run_id"
59
+
60
+ # Rerun the workflow
61
+ if gh run rerun "$run_id" --repo monte-carlo-data/monolith-django; then
62
+ success "Successfully triggered workflow rerun for monolith PR #$monolith_pr"
63
+ return 0
64
+ else
65
+ error "Failed to rerun workflow for monolith PR #$monolith_pr"
66
+ return 1
67
+ fi
68
+ }
69
+
70
+ info "Checking for existing PRs with same changes as main..."
71
+
72
+ # Check for clean working directory
73
+ if ! git diff --quiet || ! git diff --cached --quiet; then
74
+ error "Working directory has uncommitted changes. Please commit or stash them before running this script."
75
+ exit 1
76
+ fi
77
+
78
+ # Get all open PRs that match our branch naming pattern
79
+ OPEN_PRS=$(gh pr list --base main --search "update-types-from-monolith- in:title is:open" --json number,headRefName,url --jq '.[]')
80
+
81
+ git fetch -q origin main
82
+ for pr in $(echo "${OPEN_PRS}" | jq -c '.'); do
83
+ PR_NUMBER=$(echo "$pr" | jq -r '.number')
84
+ PR_BRANCH=$(echo "$pr" | jq -r '.headRefName')
85
+ PR_URL=$(echo "$pr" | jq -r '.url')
86
+ MONOLITH_PR=$(echo "$PR_BRANCH" | sed -n 's/.*update-types-from-monolith-\([0-9]*\).*/\1/p')
87
+
88
+ info "Comparing current branch with PR #$PR_NUMBER (branch: $PR_BRANCH)..."
89
+
90
+ # Check if the related monolith PR is closed/merged
91
+ # If so, we will go ahead and close the SDK PR because
92
+ # it's more likely than not no longer needed and any changes
93
+ # should already be in main or will get into main via one of the open ones
94
+ if [ -n "$MONOLITH_PR" ]; then
95
+ info "Checking status of monolith PR #$MONOLITH_PR..."
96
+ MONOLITH_STATUS=$(gh pr view "$MONOLITH_PR" --repo monte-carlo-data/monolith-django --json state --jq '.state' 2>/dev/null || echo "NOT_FOUND")
97
+
98
+ if [ "$MONOLITH_STATUS" = "CLOSED" ] || [ "$MONOLITH_STATUS" = "MERGED" ]; then
99
+ warn "Monolith PR #$MONOLITH_PR is $MONOLITH_STATUS. Closing SDK PR #$PR_NUMBER..."
100
+ gh pr close "$PR_NUMBER" --delete-branch --comment "Closing this PR as the related monolith PR #$MONOLITH_PR has been $MONOLITH_STATUS."
101
+ echo
102
+ continue
103
+ elif [ "$MONOLITH_STATUS" = "NOT_FOUND" ]; then
104
+ warn "Could not find monolith PR #$MONOLITH_PR"
105
+ else
106
+ info "Monolith PR #$MONOLITH_PR is still open ($MONOLITH_STATUS)"
107
+ fi
108
+ fi
109
+
110
+ # Fetch the PR branch and main
111
+ git fetch -q origin "$PR_BRANCH"
112
+
113
+ # Track whether PR should be closed
114
+ is_same_as_main=false
115
+
116
+ # Fetch the PR branch
117
+ if ! git fetch -q origin "$PR_BRANCH"; then
118
+ error "Failed to fetch branch $PR_BRANCH for PR #$PR_NUMBER. Skipping..."
119
+ continue
120
+ fi
121
+
122
+ # Compare PR branch with main
123
+ if git diff --quiet origin/"$PR_BRANCH" origin/main; then
124
+ info "Existing PR #$PR_NUMBER is same as main: $PR_URL"
125
+ is_same_as_main=true
126
+ else
127
+ # Create a temporary branch from the PR branch
128
+ if ! git checkout -q -b temp_"$PR_BRANCH" origin/"$PR_BRANCH" 2>/dev/null; then
129
+ error "Failed to checkout branch $PR_BRANCH for PR #$PR_NUMBER. Skipping..."
130
+ continue
131
+ fi
132
+
133
+ # Attempt to merge latest from main into the temporary branch
134
+ if git merge --quiet origin/main --no-ff -m "Merging latest from main" > /dev/null 2>&1; then
135
+ # Now compare with main
136
+ if git diff --quiet origin/main; then
137
+ info "PR #$PR_NUMBER is now same as main after merging: $PR_URL"
138
+ is_same_as_main=true
139
+ else
140
+ info "PR #$PR_NUMBER still has changes compared to main: $PR_URL"
141
+ fi
142
+ else
143
+ warn "Merge conflict detected for PR #$PR_NUMBER. Closing to allow fresh regeneration..."
144
+ # Clean up: abort the merge
145
+ git merge --abort
146
+ # Switch back to original branch and delete the temporary branch
147
+ git checkout -q -
148
+ git branch -q -D temp_"$PR_BRANCH"
149
+ # Close the PR
150
+ info "API repo PR: https://github.com/monte-carlo-data/monolith-django/pull/$MONOLITH_PR"
151
+ gh pr close "$PR_NUMBER" --delete-branch --comment "Closing this PR due to merge conflicts with main. Types will be regenerated on the next update."
152
+
153
+ # Rerun the workflow for the monolith PR
154
+ rerun_generation "$MONOLITH_PR"
155
+
156
+ continue
157
+ fi
158
+
159
+ # Switch back to original branch and delete the temporary branch
160
+ git checkout -q -
161
+ git branch -q -D temp_"$PR_BRANCH"
162
+ fi
163
+
164
+ # Close PR if it's the same as main
165
+ if [ "$is_same_as_main" = true ]; then
166
+ info "API repo PR: https://github.com/monte-carlo-data/monolith-django/pull/$MONOLITH_PR"
167
+ warn "Closing PR #$PR_NUMBER..."
168
+ gh pr close "$PR_NUMBER" --delete-branch --comment "Closing this PR as there are no remaining changes compared to current main."
169
+ fi
170
+ echo
171
+ done
@@ -0,0 +1,2 @@
1
+ [report]
2
+ show_missing = True
@@ -0,0 +1,66 @@
1
+ # ******** NOTE ********
2
+ # GitHub action libraries should be pinned to a commit hash, not a version tag, to avoid vulnerabilities.
3
+
4
+ name: Make new release
5
+
6
+ on:
7
+ push:
8
+ branches: [main]
9
+ paths: ['pycarlo/lib/schema.py']
10
+
11
+ permissions:
12
+ # This is required for requesting the JWT
13
+ id-token: write
14
+
15
+ # This is required for creating a release
16
+ contents: write
17
+
18
+ jobs:
19
+ create-release:
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - name: Generate GitHub token
23
+ id: generate_token
24
+ uses: tibdex/github-app-token@32691ba7c9e7063bd457bd8f2a5703138591fa58 # v1.9.0
25
+ with:
26
+ app_id: ${{ secrets.MC_GITHUB_APP_ID }}
27
+ private_key: ${{ secrets.MC_GITHUB_APP_PRIVATE_KEY }}
28
+ - name: Checkout main branch
29
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
30
+ with:
31
+ token: ${{ steps.generate_token.outputs.token }}
32
+ ref: main
33
+ path: python-sdk
34
+ - name: Get latest release tag
35
+ id: get_latest_release_tag
36
+ env:
37
+ GH_TOKEN: ${{ steps.generate_token.outputs.token }}
38
+ working-directory: python-sdk
39
+ run: |
40
+ echo "Listing releases..."
41
+ LATEST_RELEASE_TAG=$(gh release list \
42
+ --order desc \
43
+ --limit 1 \
44
+ --json tagName \
45
+ --jq '.[0].tagName')
46
+ echo "LATEST_RELEASE_TAG='$LATEST_RELEASE_TAG'"
47
+ echo "latest_release_tag=$LATEST_RELEASE_TAG" >> $GITHUB_OUTPUT
48
+ - name: Make new release tag
49
+ id: make_new_release_tag
50
+ env:
51
+ LATEST_RELEASE_TAG: ${{ steps.get_latest_release_tag.outputs.latest_release_tag }}
52
+ run: |
53
+ MAJOR_MINOR=$(echo $LATEST_RELEASE_TAG | cut -f 1-2 -d . )
54
+ PATCH=$(echo $LATEST_RELEASE_TAG | cut -f 3 -d . )
55
+ NEW_PATCH=$(( $PATCH + 1 ))
56
+ NEW_RELEASE_TAG="$MAJOR_MINOR.$NEW_PATCH"
57
+ echo "NEW_RELEASE_TAG='$NEW_RELEASE_TAG'"
58
+ echo "new_release_tag=$NEW_RELEASE_TAG" >> $GITHUB_OUTPUT
59
+ - name: Create new release
60
+ id: create_new_release
61
+ env:
62
+ GH_TOKEN: ${{ steps.generate_token.outputs.token }}
63
+ NEW_RELEASE_TAG: ${{ steps.make_new_release_tag.outputs.new_release_tag }}
64
+ working-directory: python-sdk
65
+ run: |
66
+ gh release create $NEW_RELEASE_TAG --generate-notes
@@ -0,0 +1,140 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ /lib/
18
+ !pycarlo/lib/
19
+ !tests/lib/
20
+ lib64/
21
+ parts/
22
+ sdist/
23
+ var/
24
+ wheels/
25
+ pip-wheel-metadata/
26
+ share/python-wheels/
27
+ *.egg-info/
28
+ .installed.cfg
29
+ *.egg
30
+ MANIFEST
31
+
32
+ # PyInstaller
33
+ # Usually these files are written by a python script from a template
34
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
35
+ *.manifest
36
+ *.spec
37
+
38
+ # Installer logs
39
+ pip-log.txt
40
+ pip-delete-this-directory.txt
41
+
42
+ # Unit test / coverage reports
43
+ htmlcov/
44
+ .tox/
45
+ .nox/
46
+ .coverage
47
+ .coverage.*
48
+ .cache
49
+ nosetests.xml
50
+ coverage.xml
51
+ *.cover
52
+ *.py,cover
53
+ .hypothesis/
54
+ .pytest_cache/
55
+
56
+ # Translations
57
+ *.mo
58
+ *.pot
59
+
60
+ # Django stuff:
61
+ *.log
62
+ local_settings.py
63
+ db.sqlite3
64
+ db.sqlite3-journal
65
+
66
+ # Flask stuff:
67
+ instance/
68
+ .webassets-cache
69
+
70
+ # Scrapy stuff:
71
+ .scrapy
72
+
73
+ # Sphinx documentation
74
+ docs/_build/
75
+
76
+ # PyBuilder
77
+ target/
78
+
79
+ # Jupyter Notebook
80
+ .ipynb_checkpoints
81
+
82
+ # IPython
83
+ profile_default/
84
+ ipython_config.py
85
+
86
+ # pyenv
87
+ .python-version
88
+
89
+ # pipenv
90
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
91
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
92
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
93
+ # install all needed dependencies.
94
+ #Pipfile.lock
95
+
96
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
97
+ __pypackages__/
98
+
99
+ # Celery stuff
100
+ celerybeat-schedule
101
+ celerybeat.pid
102
+
103
+ # SageMath parsed files
104
+ *.sage.py
105
+
106
+ # Environments
107
+ .env
108
+ .venv
109
+ env/
110
+ venv/
111
+ ENV/
112
+ env.bak/
113
+ venv.bak/
114
+
115
+ # Spyder project settings
116
+ .spyderproject
117
+ .spyproject
118
+
119
+ # Rope project settings
120
+ .ropeproject
121
+
122
+ # mkdocs documentation
123
+ /site
124
+
125
+ # mypy
126
+ .mypy_cache/
127
+ .dmypy.json
128
+ dmypy.json
129
+
130
+ # Pyre type checker
131
+ .pyre/
132
+
133
+ .idea/
134
+
135
+ .DS_Store
136
+
137
+ .ruff_cache/
138
+
139
+ # used in tests/test_forgiving_enums_published.sh
140
+ test-forgiving-enums-venv
@@ -0,0 +1,31 @@
1
+ repos:
2
+ - repo: local
3
+ hooks:
4
+ - id: ruff-format
5
+ name: ruff format
6
+ entry: ruff
7
+ language: system
8
+ types: [python]
9
+ pass_filenames: true
10
+ args: [format]
11
+ exclude: ^(pycarlo/lib/schema\.py|tests/data/schema_original\.py)$
12
+ - repo: local
13
+ hooks:
14
+ - id: ruff-check
15
+ name: ruff check
16
+ entry: ruff
17
+ language: system
18
+ types: [python]
19
+ pass_filenames: true
20
+ args: [check, --fix, --exit-non-zero-on-fix]
21
+ exclude: ^(pycarlo/lib/schema\.py|tests/data/schema_original\.py)$
22
+ - repo: local
23
+ hooks:
24
+ - id: pyright
25
+ name: pyright
26
+ entry: pyright
27
+ language: system
28
+ types: [python]
29
+ pass_filenames: true
30
+ args: [--level, error]
31
+ exclude: ^(pycarlo/lib/schema\.py|tests/data/schema_original\.py)$
@@ -0,0 +1,47 @@
1
+ # Contribution Guidelines
2
+
3
+ This is primarily for Monte Carlo developers. External contributions are welcome, but you may want
4
+ to reach out though support first to discuss your proposed changes.
5
+
6
+ ## Setting up for development
7
+
8
+ ```sh
9
+ make install-dev
10
+ ```
11
+
12
+ This will create a virtual environment, install dependencies, and set up pre-commit hooks.
13
+
14
+ ## Updating Typed Schema to Match GraphQL API
15
+
16
+ The schema is automatically kept up-to-date by our CI pipeline when changes are merged to the API
17
+ repo. You typically don't need to run `make generate` unless you're testing or debugging an issue
18
+ locally.
19
+
20
+ If you do need to manually update the schema for testing on your development machine, use
21
+ `make generate`. This will fetch the latest schema from the API and regenerate the Python types,
22
+ including any customizations.
23
+
24
+ ## Schema Customizations
25
+
26
+ The generated `schema.py` is automatically modified during the build process to apply the following
27
+ customizations. See [pycarlo/lib/README.md](pycarlo/lib/README.md) for more details. If you need to
28
+ make additional customizations, you need to do so through that process.
29
+
30
+ ## Testing
31
+
32
+ `make test` can be used to run all tests locally. CircleCI manages testing for deployment.
33
+
34
+ ## Releases
35
+
36
+ Our CI pipeline is configured to automatically update the schema and run tests when changes are
37
+ merged to the default branch in our API repo. It will also automatically deploy a new versioned
38
+ release.
39
+
40
+ ### Custom Releases
41
+
42
+ If you need to make a custom release, create a PR against `main`.
43
+
44
+ When ready to release after merging, create a new
45
+ [Github release](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository)
46
+ with a tag using semantic versioning (e.g. `v0.42.0`) and CircleCI will test and publish to PyPI.
47
+ Note that an existing version will not be deployed.
@@ -0,0 +1,135 @@
1
+ .PHONY: default clean install install-dev pip-install generate generate-local retrieve-schema transform-schema format-schema update-test-schema customize-schema env-check-venv test sanity-check
2
+ .SILENT: generate generate-local # Prevent echoing of any tokens
3
+
4
+ PACKAGE_NAME=pycarlo
5
+ ENVIRONMENT_NAME=venv
6
+ MCD_URL=https://api.getmontecarlo.com/graphql
7
+
8
+ # Schema generator util
9
+ SCHEMA_GEN_UTIL=utils/generate.py
10
+ SANITY_CHECK_UTIL=utils/sanity.py
11
+ ENV_UTIL=utils/env.sh
12
+ ENV_FILE=utils/.env
13
+ SAMPLE_ENV_FILE=utils/sample.env
14
+
15
+ # Generated schema destinations
16
+ SCHEMA_FROM_INTROSPECTION=$(PACKAGE_NAME)/lib/schema.json
17
+ SCHEMA_PY=$(PACKAGE_NAME)/lib/schema.py
18
+ SCHEMA_TEST_DATA=tests/data/schema_original.py
19
+
20
+ default:
21
+ @echo "Refer to CONTRIBUTING.md for details on common tasks."
22
+
23
+ clean:
24
+ @echo "Cleaning up existing build artifacts..."; \
25
+ rm -rf $(ENVIRONMENT_NAME) build dist $(PACKAGE_NAME).egg-info .coverage nosetests.xml
26
+
27
+ pip-install:
28
+ @echo "\nInstalling Python package in editable mode..."; \
29
+ pip install --editable .
30
+
31
+ install: clean
32
+ ifeq ("$(wildcard $(ENV_FILE))","")
33
+ @echo "\nCreating env file from sample..."; \
34
+ cp $(SAMPLE_ENV_FILE) $(ENV_FILE)
35
+ endif
36
+ @echo "\nCreating virtual environment..."; \
37
+ python3 -m venv $(ENVIRONMENT_NAME);
38
+ @echo "\nInstalling dependencies..."; \
39
+ . $(ENVIRONMENT_NAME)/bin/activate; \
40
+ pip install -r requirements-dev.txt; \
41
+ $(MAKE) pip-install; \
42
+ pip show $(PACKAGE_NAME)
43
+
44
+ # Full development setup = install + pre-commit hooks
45
+ install-dev: install
46
+ @echo "\nInstalling pre-commit hooks..."; \
47
+ . $(ENVIRONMENT_NAME)/bin/activate; \
48
+ pre-commit install; \
49
+ echo ""; \
50
+ echo "\033[0;32m✅ Development environment ready!\033[0m"; \
51
+ echo "\nActivate with: . $(ENVIRONMENT_NAME)/bin/activate"
52
+
53
+ sanity-check: env-check-venv
54
+ @echo "\nRunning sanity checks..."; \
55
+ . $(ENVIRONMENT_NAME)/bin/activate; \
56
+ sh $(ENV_UTIL) python $(SANITY_CHECK_UTIL); \
57
+
58
+ # Requires .env or profile credentials setup before usage.
59
+ retrieve-schema:
60
+ @echo "\nRetrieving latest schema..."; \
61
+ . $(ENVIRONMENT_NAME)/bin/activate; \
62
+ sh $(ENV_UTIL) python $(SCHEMA_GEN_UTIL) $(MCD_URL) $(SCHEMA_FROM_INTROSPECTION);
63
+
64
+ # Expects $(SCHEMA_FROM_INTROSPECTION) to already exist.
65
+ transform-schema:
66
+ @echo "\nGenerating Python types from schema.json..."; \
67
+ . $(ENVIRONMENT_NAME)/bin/activate; \
68
+ sgqlc-codegen schema --docstrings $(SCHEMA_FROM_INTROSPECTION) $(SCHEMA_PY);
69
+
70
+ format-schema:
71
+ @echo "\nFormatting Python code..."; \
72
+ . $(ENVIRONMENT_NAME)/bin/activate; \
73
+ ruff format $(SCHEMA_PY);
74
+
75
+ update-test-schema:
76
+ @echo "\nUpdating test data with original schema..."; \
77
+ mkdir -p tests/data; \
78
+ cp $(SCHEMA_PY) $(SCHEMA_TEST_DATA);
79
+
80
+ customize-schema:
81
+ @echo "\nApplying schema customizations..."; \
82
+ if [ "$$(uname)" = "Darwin" ]; then \
83
+ sed -i '' 's/class Connection(sgqlc.types.relay.Connection):/class Connection(sgqlc.types.Type):/g' $(SCHEMA_PY); \
84
+ sed -i '' 's/import sgqlc.types$$/import sgqlc.types\nimport pycarlo.lib.types/g' $(SCHEMA_PY); \
85
+ sed -i '' 's/class \([A-Za-z0-9_]*\)(sgqlc.types.Enum):/class \1(pycarlo.lib.types.Enum):/g' $(SCHEMA_PY); \
86
+ else \
87
+ sed -i 's/class Connection(sgqlc.types.relay.Connection):/class Connection(sgqlc.types.Type):/g' $(SCHEMA_PY); \
88
+ sed -i 's/import sgqlc.types$$/import sgqlc.types\nimport pycarlo.lib.types/g' $(SCHEMA_PY); \
89
+ sed -i 's/class \([A-Za-z0-9_]*\)(sgqlc.types.Enum):/class \1(pycarlo.lib.types.Enum):/g' $(SCHEMA_PY); \
90
+ fi; \
91
+ echo "*************"; \
92
+ echo "The following schema customizations have been applied:"; \
93
+ echo " 1. Changed 'class Connection(sgqlc.types.relay.Connection)' to 'class Connection(sgqlc.types.Type)'"; \
94
+ echo " 2. Changed all Enum classes to use 'pycarlo.lib.types.Enum' for backward compatibility"; \
95
+ echo "*************"; \
96
+
97
+ env-check-venv:
98
+ @if [ ! -d "$(ENVIRONMENT_NAME)" ]; then \
99
+ echo "\033[0;31m❌ Error: Virtual environment not found. Please run 'make install' first.\033[0m"; \
100
+ exit 1; \
101
+ fi
102
+
103
+ # Generate schema from existing schema.json (skip retrieval).
104
+ # Used by CI when schema.json is already provided.
105
+ generate-local: env-check-venv transform-schema format-schema update-test-schema customize-schema
106
+ @echo "\n\033[0;32m✅ Schema generation complete!\033[0m";
107
+
108
+ # Requires .env or profile credentials setup before usage.
109
+ generate: env-check-venv retrieve-schema generate-local
110
+
111
+ test: env-check-venv
112
+ @echo "\nRunning tests..."; \
113
+ . $(ENVIRONMENT_NAME)/bin/activate; \
114
+ export DEBUG=True; \
115
+ pytest --durations=5 ./tests; \
116
+ echo ""; \
117
+ echo "Linting and formatting..."; \
118
+ ruff check .; \
119
+ ruff format --check .; \
120
+ echo ""; \
121
+ echo "Type checking..."; \
122
+ pyright .
123
+ @echo "\n\033[0;32m✅ All tests and checks passed!\033[0m";
124
+
125
+ # this is only used by CI. See circleci/config.yml:
126
+ distribute: install
127
+ @echo "\nInstalling dependencies..."; \
128
+ . $(ENVIRONMENT_NAME)/bin/activate; \
129
+ pip install -r requirements-ci.txt; \
130
+ echo "\nRunning setup..."; \
131
+ python setup.py sdist bdist_wheel; \
132
+ echo "\nChecking distribution..."; \
133
+ twine check dist/*; \
134
+ echo "\nUploading distribution to PyPI..."; \
135
+ twine upload --non-interactive dist/*