closeyourit 0.1.0__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.
Files changed (74) hide show
  1. closeyourit-0.1.0/.env.example +7 -0
  2. closeyourit-0.1.0/.github/actionlint.yaml +19 -0
  3. closeyourit-0.1.0/.github/workflows/ci.yml +70 -0
  4. closeyourit-0.1.0/.github/workflows/publish.yml +106 -0
  5. closeyourit-0.1.0/.gitignore +43 -0
  6. closeyourit-0.1.0/CHANGELOG.md +24 -0
  7. closeyourit-0.1.0/CLAUDE.md +80 -0
  8. closeyourit-0.1.0/PKG-INFO +413 -0
  9. closeyourit-0.1.0/README.md +363 -0
  10. closeyourit-0.1.0/contracts/ingest/LOCK.json +6 -0
  11. closeyourit-0.1.0/contracts/ingest/v1/README.md +18 -0
  12. closeyourit-0.1.0/contracts/ingest/v1/SHA256SUMS +14 -0
  13. closeyourit-0.1.0/contracts/ingest/v1/fixtures/http/cases.json +14 -0
  14. closeyourit-0.1.0/contracts/ingest/v1/fixtures/invalid/event-without-message-or-exception.json +8 -0
  15. closeyourit-0.1.0/contracts/ingest/v1/fixtures/invalid/log-with-blank-message.json +8 -0
  16. closeyourit-0.1.0/contracts/ingest/v1/fixtures/invalid/metric-with-blank-label.json +9 -0
  17. closeyourit-0.1.0/contracts/ingest/v1/fixtures/invalid/metric-with-unknown-kind.json +8 -0
  18. closeyourit-0.1.0/contracts/ingest/v1/fixtures/valid/events/exception-python.json +31 -0
  19. closeyourit-0.1.0/contracts/ingest/v1/fixtures/valid/events/message-python.json +11 -0
  20. closeyourit-0.1.0/contracts/ingest/v1/fixtures/valid/logs/single-python.json +11 -0
  21. closeyourit-0.1.0/contracts/ingest/v1/fixtures/valid/metrics/performance-issue.json +10 -0
  22. closeyourit-0.1.0/contracts/ingest/v1/fixtures/valid/metrics/slow-method-python.json +9 -0
  23. closeyourit-0.1.0/contracts/ingest/v1/fixtures/valid/metrics/slow-query.json +9 -0
  24. closeyourit-0.1.0/contracts/ingest/v1/manifest.json +18 -0
  25. closeyourit-0.1.0/contracts/ingest/v1/schema.json +207 -0
  26. closeyourit-0.1.0/mise.toml +2 -0
  27. closeyourit-0.1.0/pyproject.toml +109 -0
  28. closeyourit-0.1.0/scripts/__init__.py +1 -0
  29. closeyourit-0.1.0/scripts/check_release.py +54 -0
  30. closeyourit-0.1.0/src/closeyourit/__init__.py +61 -0
  31. closeyourit-0.1.0/src/closeyourit/_version.py +1 -0
  32. closeyourit-0.1.0/src/closeyourit/asgi.py +73 -0
  33. closeyourit-0.1.0/src/closeyourit/client.py +240 -0
  34. closeyourit-0.1.0/src/closeyourit/configuration.py +181 -0
  35. closeyourit-0.1.0/src/closeyourit/django.py +226 -0
  36. closeyourit-0.1.0/src/closeyourit/events.py +340 -0
  37. closeyourit-0.1.0/src/closeyourit/flask.py +66 -0
  38. closeyourit-0.1.0/src/closeyourit/hooks.py +276 -0
  39. closeyourit-0.1.0/src/closeyourit/integrations/__init__.py +24 -0
  40. closeyourit-0.1.0/src/closeyourit/integrations/_http.py +204 -0
  41. closeyourit-0.1.0/src/closeyourit/integrations/celery.py +433 -0
  42. closeyourit-0.1.0/src/closeyourit/integrations/httpx.py +158 -0
  43. closeyourit-0.1.0/src/closeyourit/integrations/requests.py +112 -0
  44. closeyourit-0.1.0/src/closeyourit/integrations/sqlalchemy.py +186 -0
  45. closeyourit-0.1.0/src/closeyourit/models.py +66 -0
  46. closeyourit-0.1.0/src/closeyourit/py.typed +1 -0
  47. closeyourit-0.1.0/src/closeyourit/scope.py +191 -0
  48. closeyourit-0.1.0/src/closeyourit/scrubber.py +157 -0
  49. closeyourit-0.1.0/src/closeyourit/sql.py +35 -0
  50. closeyourit-0.1.0/src/closeyourit/transport.py +435 -0
  51. closeyourit-0.1.0/src/closeyourit/web.py +203 -0
  52. closeyourit-0.1.0/src/closeyourit/wsgi.py +134 -0
  53. closeyourit-0.1.0/tests/__init__.py +1 -0
  54. closeyourit-0.1.0/tests/conftest.py +8 -0
  55. closeyourit-0.1.0/tests/test_asgi.py +191 -0
  56. closeyourit-0.1.0/tests/test_celery.py +517 -0
  57. closeyourit-0.1.0/tests/test_client.py +265 -0
  58. closeyourit-0.1.0/tests/test_configuration.py +168 -0
  59. closeyourit-0.1.0/tests/test_contract.py +238 -0
  60. closeyourit-0.1.0/tests/test_django_integration.py +207 -0
  61. closeyourit-0.1.0/tests/test_events.py +225 -0
  62. closeyourit-0.1.0/tests/test_flask_integration.py +116 -0
  63. closeyourit-0.1.0/tests/test_hooks.py +417 -0
  64. closeyourit-0.1.0/tests/test_http_integrations.py +318 -0
  65. closeyourit-0.1.0/tests/test_models.py +28 -0
  66. closeyourit-0.1.0/tests/test_optional_integrations.py +35 -0
  67. closeyourit-0.1.0/tests/test_package.py +7 -0
  68. closeyourit-0.1.0/tests/test_release_gate.py +44 -0
  69. closeyourit-0.1.0/tests/test_scope.py +167 -0
  70. closeyourit-0.1.0/tests/test_scrubber.py +134 -0
  71. closeyourit-0.1.0/tests/test_sql.py +20 -0
  72. closeyourit-0.1.0/tests/test_sqlalchemy_integration.py +233 -0
  73. closeyourit-0.1.0/tests/test_transport.py +376 -0
  74. closeyourit-0.1.0/tests/test_wsgi.py +424 -0
@@ -0,0 +1,7 @@
1
+ # Optional consumer configuration. The SDK itself requires no environment
2
+ # variables to install, test, or build.
3
+ CLOSEYOURIT_ENDPOINT_URL=
4
+ CLOSEYOURIT_TOKEN=
5
+ CLOSEYOURIT_PROJECT_ID=
6
+ CLOSEYOURIT_ENVIRONMENT=development
7
+ CLOSEYOURIT_RELEASE=
@@ -0,0 +1,19 @@
1
+ self-hosted-runner:
2
+ # Labels of self-hosted runner in array of strings.
3
+ labels: [hetzner-ci]
4
+
5
+ # Configuration variables in array of strings defined in your repository or
6
+ # organization. `null` means disabling configuration variables check.
7
+ # Empty array means no configuration variable is allowed.
8
+ config-variables: null
9
+
10
+ # Configuration for file paths. The keys are glob patterns to match to file
11
+ # paths relative to the repository root. The values are the configurations for
12
+ # the file paths. Note that the path separator is always '/'.
13
+ # The following configurations are available.
14
+ #
15
+ # "ignore" is an array of regular expression patterns. Matched error messages
16
+ # are ignored. This is similar to the "-ignore" command line option.
17
+ paths:
18
+ # .github/workflows/**/*.yml:
19
+ # ignore: []
@@ -0,0 +1,70 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags: ['v*.*.*']
7
+ pull_request:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ concurrency:
13
+ group: ${{ github.workflow }}-${{ github.ref }}
14
+ cancel-in-progress: ${{ github.ref_type != 'tag' }}
15
+
16
+ jobs:
17
+ quality:
18
+ runs-on: [self-hosted, hetzner-ci]
19
+ timeout-minutes: 15
20
+ steps:
21
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
22
+ with:
23
+ persist-credentials: false
24
+ - uses: jdx/mise-action@e6a8b3978addb5a52f2b4cd9d91eafa7f0ab959d # v4
25
+ - name: Create virtual environment
26
+ run: mise exec -- python -m venv .venv
27
+ - name: Install development dependencies
28
+ run: |
29
+ .venv/bin/python -m pip install --upgrade pip
30
+ .venv/bin/python -m pip install -e ".[dev]"
31
+ .venv/bin/python -m pip check
32
+ - name: Lint
33
+ run: .venv/bin/ruff check .
34
+ - name: Format
35
+ run: .venv/bin/ruff format --check .
36
+ - name: Type check
37
+ run: .venv/bin/mypy
38
+ - name: Test
39
+ run: .venv/bin/python -m pytest
40
+ - name: Build distributions
41
+ run: .venv/bin/python -m build
42
+ - name: Validate distributions
43
+ run: .venv/bin/python -m twine check dist/*
44
+ - name: Smoke-test wheel
45
+ run: |
46
+ .venv/bin/python -m venv .smoke-venv
47
+ .smoke-venv/bin/python -m pip install dist/*.whl
48
+ .smoke-venv/bin/python -c "import closeyourit; print(closeyourit.__version__)"
49
+
50
+ compatibility:
51
+ runs-on: [self-hosted, hetzner-ci]
52
+ timeout-minutes: 15
53
+ strategy:
54
+ fail-fast: false
55
+ matrix:
56
+ python: ['3.11', '3.12', '3.13', '3.14']
57
+ steps:
58
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
59
+ with:
60
+ persist-credentials: false
61
+ - uses: jdx/mise-action@e6a8b3978addb5a52f2b4cd9d91eafa7f0ab959d # v4
62
+ - name: Create virtual environment with Python ${{ matrix.python }}
63
+ run: mise exec python@${{ matrix.python }} -- python -m venv .venv
64
+ - name: Install package and test dependencies
65
+ run: |
66
+ .venv/bin/python -m pip install --upgrade pip
67
+ .venv/bin/python -m pip install -e ".[dev]"
68
+ .venv/bin/python -m pip check
69
+ - name: Test on Python ${{ matrix.python }}
70
+ run: .venv/bin/python -m pytest
@@ -0,0 +1,106 @@
1
+ name: Publish
2
+
3
+ on:
4
+ push:
5
+ tags: ['v*.*.*']
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ concurrency:
11
+ group: ${{ github.workflow }}-${{ github.ref }}
12
+ cancel-in-progress: false
13
+
14
+ jobs:
15
+ compatibility:
16
+ if: github.ref_type == 'tag' && !contains(github.ref_name, '-')
17
+ runs-on: [self-hosted, hetzner-ci]
18
+ timeout-minutes: 15
19
+ strategy:
20
+ fail-fast: false
21
+ matrix:
22
+ python: ['3.11', '3.12', '3.13', '3.14']
23
+ steps:
24
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
25
+ with:
26
+ persist-credentials: false
27
+ - uses: jdx/mise-action@e6a8b3978addb5a52f2b4cd9d91eafa7f0ab959d # v4.2.0
28
+ - name: Create virtual environment with Python ${{ matrix.python }}
29
+ run: mise exec python@${{ matrix.python }} -- python -m venv .venv
30
+ - name: Install package and test dependencies
31
+ run: |
32
+ .venv/bin/python -m pip install --upgrade pip
33
+ .venv/bin/python -m pip install -e ".[dev]"
34
+ .venv/bin/python -m pip check
35
+ - name: Test on Python ${{ matrix.python }}
36
+ run: .venv/bin/python -m pytest
37
+
38
+ build:
39
+ if: github.ref_type == 'tag' && !contains(github.ref_name, '-')
40
+ runs-on: [self-hosted, hetzner-ci]
41
+ timeout-minutes: 15
42
+ steps:
43
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
44
+ with:
45
+ persist-credentials: false
46
+ - uses: jdx/mise-action@e6a8b3978addb5a52f2b4cd9d91eafa7f0ab959d # v4.2.0
47
+ - name: Create virtual environment
48
+ run: mise exec -- python -m venv .venv
49
+ - name: Install development dependencies
50
+ run: |
51
+ .venv/bin/python -m pip install --upgrade pip
52
+ .venv/bin/python -m pip install -e ".[dev]"
53
+ .venv/bin/python -m pip check
54
+ - name: Validate release metadata
55
+ run: .venv/bin/python scripts/check_release.py --tag "$GITHUB_REF_NAME"
56
+ - name: Lint
57
+ run: .venv/bin/ruff check .
58
+ - name: Format
59
+ run: .venv/bin/ruff format --check .
60
+ - name: Type check
61
+ run: .venv/bin/mypy
62
+ - name: Test
63
+ run: .venv/bin/python -m pytest
64
+ - name: Build distributions
65
+ run: .venv/bin/python -m build
66
+ - name: Validate distributions
67
+ run: .venv/bin/python -m twine check dist/*
68
+ - name: Smoke-test wheel
69
+ run: |
70
+ mise exec -- python -m venv .smoke-wheel-venv
71
+ .smoke-wheel-venv/bin/python -m pip install dist/*.whl
72
+ .smoke-wheel-venv/bin/python -c \
73
+ "import closeyourit; assert closeyourit.__version__ == '${GITHUB_REF_NAME#v}'"
74
+ - name: Smoke-test source distribution
75
+ run: |
76
+ mise exec -- python -m venv .smoke-sdist-venv
77
+ .smoke-sdist-venv/bin/python -m pip install dist/*.tar.gz
78
+ .smoke-sdist-venv/bin/python -c \
79
+ "import closeyourit; assert closeyourit.__version__ == '${GITHUB_REF_NAME#v}'"
80
+ - name: Store verified distributions
81
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
82
+ with:
83
+ name: python-package-distributions
84
+ path: dist/
85
+ if-no-files-found: error
86
+ retention-days: 7
87
+
88
+ publish:
89
+ if: github.ref_type == 'tag' && !contains(github.ref_name, '-')
90
+ needs: [compatibility, build]
91
+ runs-on: ubuntu-latest
92
+ timeout-minutes: 10
93
+ environment:
94
+ name: pypi
95
+ url: https://pypi.org/p/closeyourit
96
+ permissions:
97
+ contents: read
98
+ id-token: write
99
+ steps:
100
+ - name: Retrieve verified distributions
101
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
102
+ with:
103
+ name: python-package-distributions
104
+ path: dist/
105
+ - name: Publish package distributions to PyPI
106
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
@@ -0,0 +1,43 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyd
5
+ *.so
6
+ .Python
7
+
8
+ # Virtual environments
9
+ .venv/
10
+ .smoke-venv/
11
+ .smoke-*-venv/
12
+ venv/
13
+
14
+ # Packaging
15
+ build/
16
+ dist/
17
+ *.egg-info/
18
+
19
+ # Test and analysis caches
20
+ .coverage
21
+ coverage.xml
22
+ htmlcov/
23
+ .pytest_cache/
24
+ .mypy_cache/
25
+ .ruff_cache/
26
+
27
+ # Local tooling
28
+ .firecrawl/
29
+ .mise.local.toml
30
+
31
+ # Secrets and local configuration
32
+ .env
33
+ .env.*
34
+ !.env.example
35
+ *.key
36
+
37
+ # Editors and operating systems
38
+ .DS_Store
39
+ .idea/
40
+ .vscode/
41
+ *.swp
42
+ *.swo
43
+ *~
@@ -0,0 +1,24 @@
1
+ # Changelog
2
+
3
+ Tutte le modifiche rilevanti dello SDK saranno documentate in questo file.
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [0.1.0] - 2026-07-13
8
+
9
+ ### Added
10
+
11
+ - Scaffold Python tipizzato con test, coverage, lint, type check e build del package.
12
+ - Pipeline di pubblicazione PyPI tramite Trusted Publishing OIDC, senza token permanenti.
13
+ - Configurazione immutabile e fail-safe con validazione delle credenziali server-side.
14
+ - Scope isolato per task e thread, snapshot immutabili e scrubbing PII ricorsivo.
15
+ - Builder tipizzati per errori, messaggi, log strutturati e metriche performance.
16
+ - Client con sampling deterministico, breadcrumb limitati e protocollo di sink sostituibile.
17
+ - Transport HTTP asincrono con coda limitata, retry, diagnostica, flush, shutdown e fork safety.
18
+ - Handler `logging` e hook reversibili per errori non gestiti di sys, threading e asyncio.
19
+ - Contratto golden ingest vendorizzato con schema, fixture, matrice HTTP, lock e checksum.
20
+ - Middleware WSGI/ASGI e adapter Django/Flask con scope isolato, streaming e privacy-by-default.
21
+ - Integrazioni opzionali e reversibili per Requests, HTTPX sync/async e SQLAlchemy, con URL e SQL
22
+ privati per default, slow/repeated HTTP, query lente, conteggio query e rilevazione N+1.
23
+ - Extra Celery con signal reversibili, metriche task/coda e capture fail-safe di failure, retry e
24
+ revoche senza acquisire argomenti o risultati.
@@ -0,0 +1,80 @@
1
+ # closeyourit-python
2
+
3
+ SDK Python ufficiale, server-side, per CloseYourIt. Il contratto wire canonico vive in
4
+ `../closeyourit-docs/API.md`; non introdurre payload o autenticazioni divergenti senza aggiornare
5
+ prima il contratto e le fixture condivise.
6
+
7
+ ## Repository
8
+
9
+ - **GitHub**: https://github.com/bussolabs/closeyourit-python
10
+ - **CloseYourIt**: progetto `CYPY`
11
+ - **Visibilità**: privata
12
+
13
+ ## Runtime e comandi
14
+
15
+ Python è gestito con `mise` e fissato in `mise.toml`. Il package supporta Python 3.11+.
16
+
17
+ ```bash
18
+ mise install
19
+ mise exec -- python -m venv .venv
20
+ .venv/bin/python -m pip install -e ".[dev]"
21
+ .venv/bin/ruff check .
22
+ .venv/bin/ruff format --check .
23
+ .venv/bin/mypy
24
+ .venv/bin/python -m pytest
25
+ .venv/bin/python -m pip check
26
+ .venv/bin/python -m build
27
+ .venv/bin/python -m twine check dist/*
28
+ actionlint
29
+ ```
30
+
31
+ ## Architettura
32
+
33
+ - Codice package: `src/closeyourit/`
34
+ - Test: `tests/`
35
+ - Layout: `src`, package typed tramite `py.typed`
36
+ - Build backend: Hatchling
37
+ - API pubblica: esportata soltanto da `closeyourit/__init__.py`
38
+ - `configuration.py`: configurazione immutabile, validazione e callback `before_send` fail-safe
39
+ - `scope.py`: stato copy-on-write isolato tramite `ContextVar` e snapshot immutabili
40
+ - `scrubber.py`: filtro PII ricorsivo conforme al denylist condiviso tra SDK
41
+ - `models.py`: tipi JSON e conversione freeze/thaw senza rappresentazioni sensibili
42
+ - `events.py`: builder puri per errori, messaggi, log e metriche conformi al wire condiviso
43
+ - `client.py`: sampling, facade di capture e lifecycle `flush`/`close` del sink
44
+ - `transport.py`: HTTP standard library, coda bounded, retry/redirect, worker lazy e fork safety
45
+ - `hooks.py`: handler logging e hook sys/threading/asyncio reversibili, concatenati e fail-safe
46
+ - `web.py`: lifecycle HTTP condiviso, header allowlist, route e metriche `slow_request`
47
+ - `wsgi.py` / `asgi.py`: middleware core senza dipendenze, streaming e isolamento concorrente
48
+ - `django.py` / `flask.py`: adapter opzionali con import lazy dei framework
49
+ - `contracts/ingest/v1`: snapshot golden offline con lock e checksum della fonte canonica
50
+ - `integrations/_http.py`: URL sicuri, slow/repeated HTTP e propagazione W3C allowlisted
51
+ - `integrations/celery.py`: signal Celery opzionali, timing concorrente e contesto bounded
52
+ - `integrations/requests.py`: hook e wrapper per-session reversibile per errori e timeout
53
+ - `integrations/httpx.py`: event hook sync/async e wrapper per-client reversibile
54
+ - `integrations/sqlalchemy.py`: listener engine, fingerprint SQL e profili query via ContextVar
55
+ - `sql.py`: fingerprint SQL dependency-free condiviso da builder e integrazioni
56
+ - Dipendenze runtime core: nessuna; extra opzionali `[celery]`, `[django]`, `[flask]`, `[requests]`,
57
+ `[httpx]` e `[sqlalchemy]`
58
+
59
+ Applicare TDD red/green/refactor. Coverage minima: 90% line e branch. Testare confini numerici,
60
+ 0/1/N, timeout, retry, idempotenza, fork, shutdown, concorrenza sync/async, streaming e scrubbing
61
+ PII. I middleware web non devono mai leggere il body della richiesta; gli adapter Celery non
62
+ devono mai acquisire argomenti o risultati dei task né alterarne il controllo di flusso.
63
+
64
+ ## Variabili d'ambiente
65
+
66
+ Lo sviluppo del package non richiede segreti. Le variabili in `.env.example` documentano il
67
+ contratto per le applicazioni consumer. Valori reali esclusivamente fuori dal repository,
68
+ caricati con `doppler run`; non creare file `.env`.
69
+
70
+ ## Servizi esterni
71
+
72
+ - CloseYourIt ingest: transport verificato tramite requester e contratto golden, senza rete nei test.
73
+ - PyPI: pubblicazione esclusiva tramite Trusted Publishing OIDC in GitHub Actions.
74
+
75
+ ## Deploy e release
76
+
77
+ Non esiste un deploy applicativo. Le release usano tag stabili `vMAJOR.MINOR.PATCH` e il workflow
78
+ `.github/workflows/publish.yml`, associato al GitHub environment `pypi` e al Trusted Publisher PyPI.
79
+ Non pubblicare da locale e non configurare token PyPI permanenti. Il job con OIDC deve restare
80
+ separato da build e test; ogni tag stabile richiede versione package e `CHANGELOG.md` allineati.