Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: splunk/contentctl
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v3.3.0
Choose a base ref
...
head repository: splunk/contentctl
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Loading
Showing with 13,151 additions and 9,034 deletions.
  1. BIN .DS_Store
  2. +1 −0 .git-blame-ignore-revs
  3. +5 −0 .github/dependabot.yml
  4. +3 −3 .github/workflows/pushToPyPiOnRelease.yml
  5. +22 −0 .github/workflows/ruff.yml
  6. +23 −18 .github/workflows/testEndToEnd.yml
  7. +71 −0 .github/workflows/test_against_escu.yml
  8. +2 −0 .gitignore
  9. +15 −0 .pre-commit-config.yaml
  10. +5 −0 .vscode/extensions.json
  11. +74 −17 .vscode/launch.json
  12. +14 −1 .vscode/settings.json
  13. +39 −9 README.md
  14. +1 −1 contentctl/__init__.py
  15. +0 −98 contentctl/actions/apav_deploy.py
  16. +0 −151 contentctl/actions/api_deploy.py
  17. +136 −0 contentctl/actions/build.py
  18. +0 −25 contentctl/actions/convert.py
  19. +60 −0 contentctl/actions/deploy_acs.py
  20. +0 −149 contentctl/actions/detection_testing/DataManipulation.py
  21. +77 −54 contentctl/actions/detection_testing/DetectionTestingManager.py
  22. +215 −228 contentctl/actions/detection_testing/GitService.py
  23. +48 −30 contentctl/actions/detection_testing/generate_detection_coverage_badge.py
  24. +325 −225 contentctl/actions/detection_testing/infrastructures/DetectionTestingInfrastructure.py
  25. +67 −24 contentctl/actions/detection_testing/infrastructures/DetectionTestingInfrastructureContainer.py
  26. +9 −6 contentctl/actions/detection_testing/progress_bar.py
  27. +70 −35 contentctl/actions/detection_testing/views/DetectionTestingView.py
  28. +2 −5 contentctl/actions/detection_testing/views/DetectionTestingViewCLI.py
  29. +5 −15 contentctl/actions/detection_testing/views/DetectionTestingViewFile.py
  30. +8 −9 contentctl/actions/detection_testing/views/DetectionTestingViewWeb.py
  31. +9 −5 contentctl/actions/doc_gen.py
  32. +0 −87 contentctl/actions/generate.py
  33. +64 −71 contentctl/actions/initialize.py
  34. +0 −245 contentctl/actions/initialize_old.py
  35. +457 −0 contentctl/actions/inspect.py
  36. +171 −14 contentctl/actions/new_content.py
  37. +339 −131 contentctl/actions/release_notes.py
  38. +31 −16 contentctl/actions/reporting.py
  39. +83 −33 contentctl/actions/test.py
  40. +122 −72 contentctl/actions/validate.py
  41. +146 −0 contentctl/api.py
  42. +259 −664 contentctl/contentctl.py
  43. +144 −74 contentctl/enrichments/attack_enrichment.py
  44. +57 −72 contentctl/enrichments/cve_enrichment.py
  45. +38 −36 contentctl/enrichments/splunk_app_enrichment.py
  46. +0 −75 contentctl/helper/config_handler.py
  47. +105 −84 contentctl/helper/link_validator.py
  48. +422 −0 contentctl/helper/splunk_app.py
  49. +111 −38 contentctl/helper/utils.py
  50. +0 −144 contentctl/input/backend_splunk_ba.py
  51. +0 −66 contentctl/input/baseline_builder.py
  52. +0 −58 contentctl/input/basic_builder.py
  53. +0 −347 contentctl/input/detection_builder.py
  54. +236 −252 contentctl/input/director.py
  55. +0 −42 contentctl/input/investigation_builder.py
  56. +0 −95 contentctl/input/new_content_generator.py
  57. +86 −130 contentctl/input/new_content_questions.py
  58. +0 −68 contentctl/input/playbook_builder.py
  59. +0 −430 contentctl/input/sigma_converter.py
  60. +0 −161 contentctl/input/ssa_detection_builder.py
  61. +0 −106 contentctl/input/story_builder.py
  62. +29 −16 contentctl/input/yml_reader.py
  63. +968 −161 contentctl/objects/abstract_security_content_objects/detection_abstract.py
  64. +298 −64 contentctl/objects/abstract_security_content_objects/security_content_object_abstract.py
  65. +41 −0 contentctl/objects/alert_action.py
  66. +9 −0 contentctl/objects/annotated_types.py
  67. +0 −214 contentctl/objects/app.py
  68. +194 −0 contentctl/objects/atomic.py
  69. +7 −4 contentctl/objects/base_test.py
  70. +28 −17 contentctl/objects/base_test_result.py
  71. +82 −56 contentctl/objects/baseline.py
  72. +42 −18 contentctl/objects/baseline_tags.py
  73. +1,187 −120 contentctl/objects/config.py
  74. +57 −43 contentctl/objects/constants.py
  75. +470 −260 contentctl/objects/correlation_search.py
  76. +114 −0 contentctl/objects/dashboard.py
  77. +44 −17 contentctl/objects/data_source.py
  78. +80 −26 contentctl/objects/deployment.py
  79. +4 −3 contentctl/objects/deployment_email.py
  80. +5 −3 contentctl/objects/deployment_notable.py
  81. +8 −7 contentctl/objects/deployment_phantom.py
  82. +4 −4 contentctl/objects/deployment_rba.py
  83. +4 −4 contentctl/objects/deployment_scheduling.py
  84. +4 −3 contentctl/objects/deployment_slack.py
  85. +5 −31 contentctl/objects/detection.py
  86. +72 −0 contentctl/objects/detection_metadata.py
  87. +84 −0 contentctl/objects/detection_stanza.py
  88. +283 −150 contentctl/objects/detection_tags.py
  89. +102 −0 contentctl/objects/drilldown.py
  90. +325 −54 contentctl/objects/enums.py
  91. +197 −0 contentctl/objects/errors.py
  92. +5 −7 contentctl/objects/integration_test.py
  93. +2 −7 contentctl/objects/integration_test_result.py
  94. +98 −57 contentctl/objects/investigation.py
  95. +42 −6 contentctl/objects/investigation_tags.py
  96. +349 −49 contentctl/objects/lookup.py
  97. +73 −57 contentctl/objects/macro.py
  98. +32 −0 contentctl/objects/manual_test.py
  99. +9 −0 contentctl/objects/manual_test_result.py
  100. +108 −5 contentctl/objects/mitre_attack_enrichment.py
  101. +2 −1 contentctl/objects/notable_action.py
  102. +19 −0 contentctl/objects/notable_event.py
  103. +0 −45 contentctl/objects/observable.py
  104. +62 −30 contentctl/objects/playbook.py
  105. +56 −9 contentctl/objects/playbook_tags.py
  106. +147 −0 contentctl/objects/rba.py
  107. +0 −163 contentctl/objects/repo_config.py
  108. +21 −17 contentctl/objects/risk_analysis_action.py
  109. +284 −0 contentctl/objects/risk_event.py
  110. +1 −0 contentctl/objects/risk_object.py
  111. +198 −0 contentctl/objects/savedsearches_conf.py
  112. +6 −7 contentctl/objects/security_content_object.py
  113. +0 −152 contentctl/objects/ssa_detection.py
  114. +0 −145 contentctl/objects/ssa_detection_tags.py
  115. +143 −45 contentctl/objects/story.py
  116. +60 −31 contentctl/objects/story_tags.py
  117. +13 −0 contentctl/objects/test_attack_data.py
  118. +0 −630 contentctl/objects/test_config.py
  119. +8 −5 contentctl/objects/test_group.py
  120. +1 −0 contentctl/objects/threat_object.py
  121. +55 −0 contentctl/objects/throttling.py
  122. +8 −19 contentctl/objects/unit_test.py
  123. +0 −22 contentctl/objects/unit_test_attack_data.py
  124. +5 −5 contentctl/objects/unit_test_baseline.py
  125. +0 −9 contentctl/objects/unit_test_old.py
  126. +14 −7 contentctl/objects/unit_test_result.py
  127. +234 −149 contentctl/output/api_json_output.py
  128. +28 −17 contentctl/output/attack_nav_output.py
  129. +30 −38 contentctl/output/attack_nav_writer.py
  130. +0 −153 contentctl/output/ba_yml_output.py
  131. +265 −397 contentctl/output/conf_output.py
  132. +384 −38 contentctl/output/conf_writer.py
  133. +52 −0 contentctl/output/data_source_writer.py
  134. +0 −28 contentctl/output/detection_writer.py
  135. +53 −27 contentctl/output/doc_md_output.py
  136. +0 −91 contentctl/output/finding_report_writer.py
  137. +20 −16 contentctl/output/jinja_writer.py
  138. +27 −5 contentctl/output/json_writer.py
  139. +0 −60 contentctl/output/new_content_yml_output.py
  140. +57 −49 contentctl/output/svg_output.py
  141. +8 −4 contentctl/output/templates/analyticstories_detections.j2
  142. +5 −5 contentctl/output/templates/analyticstories_investigations.j2
  143. +6 −6 contentctl/output/templates/analyticstories_stories.j2
  144. +18 −16 contentctl/output/templates/app.conf.j2
  145. +4 −3 contentctl/output/templates/app.manifest.j2
  146. +1 −1 contentctl/output/templates/collections.j2
  147. +6 −8 contentctl/output/templates/detection_coverage.j2
  148. +2 −2 contentctl/output/templates/doc_detection_page.j2
  149. +2 −7 contentctl/output/templates/doc_detections.j2
  150. +1 −1 contentctl/output/templates/doc_stories.j2
  151. +1 −1 contentctl/output/templates/es_investigations_investigations.j2
  152. +1 −1 contentctl/output/templates/es_investigations_stories.j2
  153. +0 −30 contentctl/output/templates/finding_report.j2
  154. +2 −1 contentctl/output/templates/header.j2
  155. +6 −10 contentctl/output/templates/macros.j2
  156. +0 −7 contentctl/output/templates/macros_detections.j2
  157. +7 −8 contentctl/output/templates/savedsearches_baselines.j2
  158. +52 −52 contentctl/output/templates/savedsearches_detections.j2
  159. +7 −8 contentctl/output/templates/savedsearches_investigations.j2
  160. +4 −0 contentctl/output/templates/server.conf.j2
  161. +0 −7 contentctl/output/templates/splunk_app/README.md
  162. +0 −31 contentctl/output/templates/splunk_app/default/app.conf
  163. +0 −2 contentctl/output/templates/splunk_app/default/content-version.conf
  164. +0 −5 contentctl/output/templates/splunk_app/default/distsearch.conf
  165. +0 −73 contentctl/output/templates/splunk_app/default/usage_searches.conf
  166. +9 −11 contentctl/output/templates/transforms.j2
  167. +0 −66 contentctl/output/yml_output.py
  168. +51 −4 contentctl/output/yml_writer.py
  169. +0 −2 contentctl/templates/README
  170. +10 −0 contentctl/templates/README.md
  171. +7 −0 contentctl/templates/app_template/README.md
  172. 0 contentctl/{output/templates/splunk_app → templates/app_template}/README/essoc_story_detail.txt
  173. 0 contentctl/{output/templates/splunk_app → templates/app_template}/README/essoc_summary.txt
  174. 0 contentctl/{output/templates/splunk_app → templates/app_template}/README/essoc_usage_dashboard.txt
  175. 0 contentctl/{output/templates/splunk_app → templates/app_template}/default/analytic_stories.conf
  176. 0 contentctl/{output/templates/splunk_app → templates/app_template}/default/commands.conf
  177. +1 −0 contentctl/{output/templates/splunk_app → templates/app_template}/default/data/ui/nav/default.xml
  178. 0 ...ctl/{output/templates/splunk_app → templates/app_template}/default/data/ui/views/escu_summary.xml
  179. 0 contentctl/{output/templates/splunk_app → templates/app_template}/default/data/ui/views/feedback.xml
  180. 0 contentctl/{output/templates/splunk_app → templates/app_template}/default/use_case_library.conf
  181. +638 −0 contentctl/templates/app_template/lookups/mitre_enrichment.csv
  182. +1 −1 contentctl/{output/templates/splunk_app → templates/app_template}/metadata/default.meta
  183. BIN contentctl/{output/templates/splunk_app → templates/app_template}/static/appIcon.png
  184. BIN contentctl/{output/templates/splunk_app → templates/app_template}/static/appIconAlt.png
  185. BIN contentctl/{output/templates/splunk_app → templates/app_template}/static/appIconAlt_2x.png
  186. BIN contentctl/{output/templates/splunk_app → templates/app_template}/static/appIcon_2x.png
  187. +171 −0 contentctl/templates/data_sources/sysmon_eventid_1.yml
  188. +1 −2 contentctl/templates/deployments/{00_default_anomaly.yml → escu_default_configuration_anomaly.yml}
  189. +1 −2 contentctl/templates/deployments/{00_default_baseline.yml → escu_default_configuration_baseline.yml}
  190. +2 −2 ...l/templates/deployments/{00_default_correlation.yml → escu_default_configuration_correlation.yml}
  191. +2 −2 contentctl/templates/deployments/{00_default_hunting.yml → escu_default_configuration_hunting.yml}
  192. +1 −2 contentctl/templates/deployments/{00_default_ttp.yml → escu_default_configuration_ttp.yml}
  193. 0 contentctl/templates/detections/application/.gitkeep
  194. 0 contentctl/templates/detections/cloud/.gitkeep
  195. +27 −38 contentctl/templates/detections/{ → endpoint}/anomalous_usage_of_7zip.yml
  196. 0 contentctl/templates/detections/network/.gitkeep
  197. 0 contentctl/templates/detections/web/.gitkeep
  198. +1 −1 contentctl/templates/stories/cobalt_strike.yml
  199. +100 −0 docs/contentctl_v5_migration_guide.md
  200. BIN docs/validation_error.png
  201. +99 −19 pyproject.toml
  202. +1 −1 tests/test_splunk_contentctl.py
Binary file removed .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ff87bcaf1741e8ecf15cb8d401438592dfef3ba7 # Mass reformat with adoption of ruff
5 changes: 5 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -12,3 +12,8 @@ updates:
schedule:
interval: "daily"
open-pull-requests-limit: 6
- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every week
interval: "weekly"
6 changes: 3 additions & 3 deletions .github/workflows/pushToPyPiOnRelease.yml
Original file line number Diff line number Diff line change
@@ -11,13 +11,13 @@ jobs:

#Checkout the current branch
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4

#Install the given version of Python we will test against
- name: Install Required Python Version
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.9"
python-version: "3.11"
architecture: "x64"

- name: Install Poetry
22 changes: 22 additions & 0 deletions .github/workflows/ruff.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: lint & format
on:
pull_request:
types: [opened, reopened, synchronize]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install ruff
run: |
python -m pip install --upgrade pip
pip install ruff
- name: Run lint
run: ruff check --output-format=github contentctl/
- name: Run Formatter
run: ruff format --check contentctl/
41 changes: 23 additions & 18 deletions .github/workflows/testEndToEnd.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
name: testEndToEnd
on:
push:
pull_request:
types: [opened, reopened]
types: [opened, reopened, synchronize]
schedule:
- cron: "44 4 * * *"

@@ -11,30 +10,30 @@ jobs:
strategy:
fail-fast: false
matrix:
python_version: ["3.9", "3.10", "3.11"]
operating_system: ["ubuntu-20.04", "ubuntu-22.04"]
python_version: ["3.11", "3.12", "3.13"]
operating_system: ["ubuntu-24.04", "macos-15", "windows-2022"]
#operating_system: ["ubuntu-20.04", "ubuntu-22.04", "macos-latest"]


runs-on: ${{ matrix.operating_system }}
steps:
- name: Install Docker for macOS
run: |
brew install docker
#import magic fails on macos runner
brew install libmagic
colima start
# Mapping below is required to get the Python docker library working
sudo ln -sf $HOME/.colima/default/docker.sock /var/run/docker.sock
if: matrix.operating_system == 'macos-latest'
#- name: Install Docker for macOS
# run: |
# brew install docker
# # import magic fails on macos runner
# brew install libmagic colima
# colima start
# # Mapping below is required to get the Python docker library working
# sudo ln -sf $HOME/.colima/default/docker.sock /var/run/docker.sock
# if: matrix.operating_system == 'macos-latest'

#Checkout the current branch
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4

#Install the given version of Python we will test against
- name: Install Required Python Version
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python_version }}
architecture: "x64"
@@ -51,7 +50,12 @@ jobs:
- name: Run contentctl init
run: |
cd my_splunk_content_pack
poetry run contentctl init
poetry run contentctl init
- name: Clone the AtomicRedTeam Repo
run: |
cd my_splunk_content_pack
git clone --depth 1 https://github.com/redcanaryco/atomic-red-team
- name: Run contentctl validate
run: |
@@ -65,11 +69,12 @@ jobs:
#Do not pause on a failed detection
- name: Run contentctl test
if: startsWith(matrix.operating_system, 'ubuntu')
run: |
cd my_splunk_content_pack
poetry run contentctl test --unattended
poetry run contentctl test --disable-tqdm --post-test-behavior never_pause
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: content_pack_${{ matrix.python_version }}_${{ matrix.operating_system }}
path: |
71 changes: 71 additions & 0 deletions .github/workflows/test_against_escu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# The default branch of security_content should always be correct.
# As such, we should use it in our test workflow, here, to ensure
# that contentctl is also correct and does not throw unexpected errors.

# We should remember that if contentctl introduces NEW validations that have
# note yet been fixed in security_content, we may see this workflow fail.
name: test_against_escu
on:
pull_request:
types: [opened, reopened, synchronize]
schedule:
- cron: "44 4 * * *"

jobs:
smoketest_escu:
strategy:
fail-fast: false
matrix:
python_version: ["3.11", "3.12", "3.13"]

operating_system: ["ubuntu-24.04", "macos-15"]
# Do not test against ESCU until known character encoding issue is resolved
# operating_system: ["ubuntu-20.04", "ubuntu-22.04", "macos-latest", "macos-14", "windows-2022"]


runs-on: ${{ matrix.operating_system }}
steps:
# Checkout the current branch of contentctl repo
- name: Checkout repo
uses: actions/checkout@v4

# Checkout the develop (default) branch of security_content
- name: Checkout repo
uses: actions/checkout@v4
with:
path: security_content
repository: splunk/security_content

#Install the given version of Python we will test against
- name: Install Required Python Version
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python_version }}
architecture: "x64"

- name: Install Poetry
run:
python -m pip install poetry

- name: Install contentctl and activate the shell
run: |
poetry install --no-interaction
- name: Clone the AtomicRedTeam Repo and the Mitre/CTI repos for testing enrichments
run: |
cd security_content
git clone --single-branch https://github.com/redcanaryco/atomic-red-team external_repos/atomic-red-team
git clone --single-branch https://github.com/mitre/cti external_repos/cti
# We do not separately run validate and build
# since a build ALSO performs a validate
- name: Run contentctl build
run: |
cd security_content
poetry run contentctl build --enrichments
# Do not run a test - it will take far too long!
# Do not upload any artifacts

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -3,13 +3,15 @@ poetry.lock
# usual mac files
.DS_Store
*/.DS_Store
.ruff_cache

# custom
dist/*
apps*
test_results*
attack_data*
security_content/
contentctl.yml

# Byte-compiled / optimized / DLL files
__pycache__/
15 changes: 15 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0 # Use the ref you want to point at
hooks:
- id: check-json
- id: check-symlinks
- id: check-yaml
- id: detect-private-key
- id: forbid-submodules
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.2
hooks:
- id: ruff
args: [ --fix ]
- id: ruff-format
5 changes: 5 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"recommendations": [
"charliermarsh.ruff"
]
}
91 changes: 74 additions & 17 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,76 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [

{
"name": "contentctl test",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/splunk_contentctl/contentctl.py",
"cwd": "${workspaceFolder}/splunk_contentctl",
"console": "integratedTerminal",
"justMyCode": true,
"args": ["-p", "tmp", "test"]
}
]
"configurations": [
{
"name":"contentctl (pick args)",
"type":"debugpy",
"request":"launch",
"program":"${workspaceFolder}/.venv/bin/contentctl",
"console":"integratedTerminal",
"cwd":"${env:SECURITY_CONTENT_PATH}",
"args":"${command:pickArgs}"},
{
"name": "contentctl init",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/.venv/bin/contentctl",
"cwd": "${workspaceFolder}/../ddd/",
"args": ["init"]
},
{
"name": "contentctl validate",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/.venv/bin/contentctl",
"cwd": "${workspaceFolder}/../",
"args": ["validate"]
},
{
"name": "contentctl validate enrich",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/.venv/bin/contentctl",
"cwd": "${workspaceFolder}/../",
"args": ["validate", "--enrichments"]
},
{
"name": "contentctl build",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/.venv/bin/contentctl",
"cwd": "${workspaceFolder}/../",
"args": ["build"]
},
{
"name": "contentctl build enrich",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/.venv/bin/contentctl",
"cwd": "${workspaceFolder}/../",
"args": ["build", "--enrichments"]
},
{
"name": "contentctl test",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/.venv/bin/contentctl",
"cwd": "${workspaceFolder}/../",
"args": ["test"]
},
{
"name": "contentctl --help",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/.venv/bin/contentctl",
"cwd": "${workspaceFolder}/../",
"args": ["--help"]
},
{
"name": "contentctl test detection",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/.venv/bin/contentctl",
"cwd": "${workspaceFolder}/../",
"args": ["test", "mode:selected", "--mode.files", "detections/endpoint/3cx_supply_chain_attack_network_indicators.yml"]
}
]
}
15 changes: 14 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
{
"python.terminal.activateEnvironment": true,
"python.envFile": "${workspaceFolder}/.env",
"python.testing.cwd": "${workspaceFolder}"
"python.testing.cwd": "${workspaceFolder}",
"python.languageServer": "Pylance",
"python.analysis.typeCheckingMode": "strict",
"[python]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "explicit"
},
"editor.defaultFormatter": "charliermarsh.ruff",
},
"ruff.nativeServer": "on"


}
Loading