openframe-core 1.0.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 (39) hide show
  1. openframe_core-1.0.0/.github/CHANGELOG.md +91 -0
  2. openframe_core-1.0.0/.github/requirements/docs.txt +3 -0
  3. openframe_core-1.0.0/.github/requirements/test.txt +18 -0
  4. openframe_core-1.0.0/.github/workflows/app-test.yml +41 -0
  5. openframe_core-1.0.0/.github/workflows/auto-docs.yml +74 -0
  6. openframe_core-1.0.0/.github/workflows/python-build.yml +84 -0
  7. openframe_core-1.0.0/.gitignore +218 -0
  8. openframe_core-1.0.0/LICENSE +21 -0
  9. openframe_core-1.0.0/PKG-INFO +219 -0
  10. openframe_core-1.0.0/README.md +198 -0
  11. openframe_core-1.0.0/openframe/__init__.py +1 -0
  12. openframe_core-1.0.0/openframe/core/__init__.py +1 -0
  13. openframe_core-1.0.0/openframe/core/config/__init__.py +17 -0
  14. openframe_core-1.0.0/openframe/core/config/settings.py +70 -0
  15. openframe_core-1.0.0/openframe/core/exceptions/__init__.py +39 -0
  16. openframe_core-1.0.0/openframe/core/exceptions/errors.py +189 -0
  17. openframe_core-1.0.0/openframe/core/health/__init__.py +19 -0
  18. openframe_core-1.0.0/openframe/core/health/protocol.py +94 -0
  19. openframe_core-1.0.0/openframe/core/middleware/__init__.py +55 -0
  20. openframe_core-1.0.0/openframe/core/middleware/telemetry.py +315 -0
  21. openframe_core-1.0.0/openframe/core/middleware/types.py +56 -0
  22. openframe_core-1.0.0/openframe/core/ports/__init__.py +29 -0
  23. openframe_core-1.0.0/openframe/core/ports/consumer.py +125 -0
  24. openframe_core-1.0.0/openframe/core/ports/producer.py +94 -0
  25. openframe_core-1.0.0/openframe/core/ports/repository.py +143 -0
  26. openframe_core-1.0.0/openframe/core/telemetry/__init__.py +43 -0
  27. openframe_core-1.0.0/openframe/core/telemetry/setup.py +230 -0
  28. openframe_core-1.0.0/openframe/core/tracing/__init__.py +24 -0
  29. openframe_core-1.0.0/openframe/core/tracing/proxy.py +135 -0
  30. openframe_core-1.0.0/pyproject.toml +35 -0
  31. openframe_core-1.0.0/pytest.ini +4 -0
  32. openframe_core-1.0.0/tests/conftest.py +135 -0
  33. openframe_core-1.0.0/tests/test_config.py +148 -0
  34. openframe_core-1.0.0/tests/test_exceptions.py +218 -0
  35. openframe_core-1.0.0/tests/test_health.py +118 -0
  36. openframe_core-1.0.0/tests/test_middleware.py +321 -0
  37. openframe_core-1.0.0/tests/test_middleware_types.py +147 -0
  38. openframe_core-1.0.0/tests/test_ports.py +240 -0
  39. openframe_core-1.0.0/tests/test_tracing.py +190 -0
@@ -0,0 +1,91 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ---
9
+
10
+ ## [Unreleased]
11
+
12
+ ---
13
+
14
+ ## [1.0.0] — 2026-06-13
15
+
16
+ ### Added
17
+
18
+ #### `openframe.core.exceptions`
19
+ - `AdapterError` — base exception class for all OpenFrame adapter packages. Carries `message`, `adapter`, `operation`, and `cause` fields. Implements `__str__` to produce `[adapter.operation] message — caused by: <cause>` rather than a raw tuple repr.
20
+ - `AdapterConnectionError` — raised when an adapter cannot establish a connection to its backend.
21
+ - `AdapterQueryError` — raised when an operation fails after a connection is established.
22
+ - `AdapterNotFoundError` — raised when a requested entity does not exist in the backend.
23
+ - `AdapterConfigurationError` — raised when required configuration (env vars, settings) is missing or invalid.
24
+ - `AdapterTimeoutError` — raised when an operation exceeds its configured timeout.
25
+
26
+ #### `openframe.core.config`
27
+ - `BaseAdapterSettings` — Pydantic `BaseSettings` subclass that all adapter config classes inherit from. Reads fields from environment variables automatically (case-insensitive, no prefix). Ships with four common fields: `adapter_name`, `connection_timeout` (30 s), `operation_timeout` (10 s), and `max_retries` (3). Missing required fields raise `ValidationError` at instantiation time.
28
+
29
+ #### `openframe.core.ports`
30
+ - `BaseRepository[T]` — generic `runtime_checkable` Protocol for persistence adapters. Methods: `get`, `list`, `create`, `update`, `delete`.
31
+ - `BaseProducer[T]` — generic `runtime_checkable` Protocol for message producers. Methods: `publish`, `publish_batch`, `close`.
32
+ - `BaseConsumer[T]` — generic `runtime_checkable` Protocol for message consumers. Methods: `subscribe`, `ack`, `nack`, `close`. Uses a push-based handler model via `Callable[[T], Awaitable[None]]`.
33
+
34
+ #### `openframe.core.health`
35
+ - `HealthCheck` — `runtime_checkable` Protocol with two async methods: `ping()` (low-cost liveness, e.g. `SELECT 1`) and `is_ready()` (full readiness — schema migrations, pool health).
36
+
37
+ #### `openframe.core.telemetry`
38
+ - `setup_telemetry()` — idempotent OTel SDK bootstrap. Configures OTLP trace and metric exporters when `OTEL_EXPORTER_OTLP_ENDPOINT` is set; falls back to no-op providers otherwise. Applies `LoggingInstrumentor` for automatic trace-id injection into log records.
39
+ - `get_tracer(name)` — `@lru_cache` accessor for the globally-configured `Tracer`.
40
+ - `get_meter(name)` — `@lru_cache` accessor for the globally-configured `Meter`.
41
+ - `record_lifecycle_event(event_name, attributes)` — platform-agnostic lifecycle counter. Replaces the template's `record_cold_start()`; callers pass `event_name="cold_start"`. Core remains platform-agnostic.
42
+ - Reads environment variables: `OTEL_EXPORTER_OTLP_ENDPOINT`, `OTEL_EXPORTER_OTLP_HEADERS`, `OTEL_SERVICE_NAME`, `OTEL_SERVICE_VERSION`, `OTEL_METRIC_EXPORT_INTERVAL_MS`, `OPENFRAME_ENV`.
43
+
44
+ #### `openframe.core.tracing`
45
+ - `TracingProxy` — zero-code async telemetry sidecar. Wraps any object and intercepts every async method call with an OTel child span. Span name: `{prefix}.{method_name}`. Sync methods pass through unwrapped. Uses an explicit `_cache` dict for closure reuse without method snapshotting — safe for reconnecting adapters (Postgres pools, Redis clients) that replace their own methods after reconnect.
46
+
47
+ #### `openframe.core.middleware`
48
+ - `TelemetryMiddleware` — pure ASGI telemetry middleware, compatible with FastAPI, Starlette, Litestar, and bare ASGI. Records one OTel span and five HTTP metric instruments per request. Injects `x-session-id` response header. Sets `StatusCode.ERROR` for HTTP ≥ 400, `StatusCode.OK` otherwise. Emits a structured log line per request.
49
+ - Metric instruments: `http.server.request.count` (`1`), `http.server.request.duration` (`s`), `http.server.active_requests` (`1`), `http.server.error.count` (`1`), `http.server.response.size` (`By`). Duration uses unit `"s"` per OTel HTTP semantic conventions.
50
+ - Span attributes: `http.method`, `http.target`, `http.route`, `http.scheme`, `http.status_code`, `http.user_agent`, `net.host.name`, `http.client_ip`, `app.session_id`.
51
+ - Route template extraction: raw ASGI uses `scope["path"]`; Starlette/FastAPI users get template grouping automatically via `scope["route"].path`.
52
+
53
+ #### `openframe.core.middleware.types`
54
+ - `ASGIScope`, `ASGIMessage`, `Receive`, `Send`, `ASGIApp` — stdlib-only ASGI type aliases shared across the OpenFrame ecosystem. No framework imports required.
55
+
56
+ #### Tests
57
+ - 112 tests across 8 test modules: `test_exceptions`, `test_config`, `test_ports`, `test_health`, `test_tracing`, `test_middleware`, `test_middleware_types`, `test_config`.
58
+ - `conftest.py` resets all OTel SDK global state between tests (the `Once._done` guard on `set_tracer_provider` / `set_meter_provider`, `lru_cache` entries, and the `_INITIALISED` flag) so every test receives a clean, isolated tracer and meter.
59
+
60
+ #### Package
61
+ - `pyproject.toml` with `hatchling` build backend, `requires-python = ">=3.11"`.
62
+ - `pytest.ini` with `asyncio_mode = auto` for `pytest-asyncio`.
63
+ - Namespace package declaration in `openframe/__init__.py` via `pkgutil.extend_path`.
64
+
65
+ ### Design decisions
66
+
67
+ - **Exception naming** — all exception subclasses carry the `Adapter` prefix (`AdapterConnectionError`, `AdapterTimeoutError`) to avoid shadowing the Python stdlib built-ins `ConnectionError` and `TimeoutError`.
68
+ - **No Grafana-specific auth** — `_grafana_headers()` from the production template is removed. The OTel SDK handles authentication natively via `OTEL_EXPORTER_OTLP_HEADERS`.
69
+ - **`OPENFRAME_ENV` replaces `MODAL_ENV`** — the environment tag is platform-agnostic. Modal users map `MODAL_ENV → OPENFRAME_ENV` in their `configure_env_vars()`.
70
+ - **Middleware does not call `setup_telemetry()`** — it calls `get_tracer()` and `get_meter()` directly. `setup_telemetry()` is an application startup concern (called once in a `lifespan` handler). This design makes the middleware safely composable with test fixtures that install their own providers.
71
+ - **`TracingProxy` closure safety** — the original template captured the resolved method in the closure at first access (a snapshot). This implementation resolves the method fresh on every invocation inside `_traced`, making the proxy safe for adapters that replace their own methods after reconnect.
72
+ - **Pure ASGI middleware** — uses `__call__(scope, receive, send)` rather than Starlette's `BaseHTTPMiddleware`, which has documented streaming and buffering limitations.
73
+
74
+ ### Dependencies
75
+
76
+ ```
77
+ opentelemetry-api>=1.24
78
+ opentelemetry-sdk>=1.24
79
+ opentelemetry-exporter-otlp-proto-http>=1.24
80
+ opentelemetry-semantic-conventions>=0.45b0
81
+ opentelemetry-instrumentation-logging>=0.45b0
82
+ pydantic>=2.0
83
+ pydantic-settings>=2.0
84
+ ```
85
+
86
+ Dev dependencies: `pytest>=8.0`, `pytest-asyncio>=0.23`, `httpx>=0.27`.
87
+
88
+ ---
89
+
90
+ [Unreleased]: https://github.com/openframe-org/openframe-core/compare/v1.0.0...HEAD
91
+ [1.0.0]: https://github.com/openframe-org/openframe-core/releases/tag/v1.0.0
@@ -0,0 +1,3 @@
1
+ mkdocs>=1.6
2
+ mkdocs-material>=9.5
3
+ mkdocs-swagger-ui-tag>=0.6
@@ -0,0 +1,18 @@
1
+ # Test dependencies for openframe-core CI
2
+ # Install the package first: pip install -e .
3
+ # Then: pip install -r .github/requirements/test.txt
4
+
5
+ pytest>=8.0
6
+ pytest-asyncio>=0.23
7
+ httpx>=0.27
8
+
9
+ # Core runtime deps — pinned here to lock CI against minimum supported versions.
10
+ # The package's own pyproject.toml declares the same floors; these are explicit
11
+ # to catch regressions when upstream releases a new major.
12
+ pydantic>=2.0
13
+ pydantic-settings>=2.0
14
+ opentelemetry-api>=1.24
15
+ opentelemetry-sdk>=1.24
16
+ opentelemetry-exporter-otlp-proto-http>=1.24
17
+ opentelemetry-semantic-conventions>=0.45b0
18
+ opentelemetry-instrumentation-logging>=0.45b0
@@ -0,0 +1,41 @@
1
+ name: App Testing
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - dev
7
+ - production
8
+
9
+ # Callable from other workflows (e.g. python-build.yml runs tests before publish).
10
+ workflow_call:
11
+
12
+ jobs:
13
+ test:
14
+ name: Pytest — Python ${{ matrix.python-version }}
15
+ runs-on: ubuntu-latest
16
+
17
+ strategy:
18
+ fail-fast: true
19
+ matrix:
20
+ python-version: ["3.11", "3.12"]
21
+
22
+ steps:
23
+ - name: Checkout
24
+ uses: actions/checkout@v4
25
+
26
+ - name: Setup Python ${{ matrix.python-version }}
27
+ uses: actions/setup-python@v5
28
+ with:
29
+ python-version: ${{ matrix.python-version }}
30
+ cache: pip
31
+
32
+ - name: Install package in editable mode
33
+ run: |
34
+ python -m pip install --upgrade pip
35
+ pip install -e .
36
+
37
+ - name: Install test dependencies
38
+ run: pip install -r .github/requirements/test.txt
39
+
40
+ - name: Run tests
41
+ run: python -m pytest tests/ -v --tb=short
@@ -0,0 +1,74 @@
1
+ name: Auto Docs
2
+
3
+ # Deploy docs to GitHub Pages on every push to production.
4
+ # On PRs to dev or production, only build (validate) — do not deploy.
5
+ on:
6
+ push:
7
+ branches:
8
+ - production
9
+
10
+ pull_request:
11
+ branches:
12
+ - dev
13
+ - production
14
+
15
+ jobs:
16
+ # ── 1. Build docs (runs on every PR to validate the docs compile) ────────
17
+ build-docs:
18
+ name: Build Documentation
19
+ runs-on: ubuntu-latest
20
+
21
+ steps:
22
+ - name: Checkout
23
+ uses: actions/checkout@v4
24
+
25
+ - name: Setup Python
26
+ uses: actions/setup-python@v5
27
+ with:
28
+ python-version: "3.11"
29
+ cache: pip
30
+
31
+ - name: Install docs dependencies
32
+ run: |
33
+ python -m pip install --upgrade pip
34
+ pip install -r .github/requirements/docs.txt
35
+
36
+ - name: Build docs (validate only)
37
+ run: mkdocs build --strict
38
+
39
+ # ── 2. Deploy docs to GitHub Pages (production merges only) ─────────────
40
+ deploy-docs:
41
+ name: Deploy Documentation
42
+ needs: build-docs
43
+ runs-on: ubuntu-latest
44
+
45
+ # Only deploy when a commit lands on production, not on PRs.
46
+ if: github.event_name == 'push' && github.ref == 'refs/heads/production'
47
+
48
+ permissions:
49
+ contents: write # required for gh-deploy to push to gh-pages branch
50
+
51
+ steps:
52
+ - name: Checkout
53
+ uses: actions/checkout@v4
54
+ with:
55
+ fetch-depth: 0 # full history needed for mkdocs git-revision-date plugins
56
+
57
+ - name: Setup Python
58
+ uses: actions/setup-python@v5
59
+ with:
60
+ python-version: "3.11"
61
+ cache: pip
62
+
63
+ - name: Install docs dependencies
64
+ run: |
65
+ python -m pip install --upgrade pip
66
+ pip install -r .github/requirements/docs.txt
67
+
68
+ - name: Configure Git for gh-deploy
69
+ run: |
70
+ git config user.name "github-actions[bot]"
71
+ git config user.email "github-actions[bot]@users.noreply.github.com"
72
+
73
+ - name: Deploy docs to GitHub Pages
74
+ run: mkdocs gh-deploy --force
@@ -0,0 +1,84 @@
1
+ name: Build & Publish Python Package
2
+
3
+ # Triggers on every push to production (i.e. after a PR is merged).
4
+ # Runs the full test suite first; publish is blocked until all tests pass.
5
+ on:
6
+ push:
7
+ branches:
8
+ - production
9
+
10
+ jobs:
11
+ # ── 1. Gate: full test suite must pass before anything is published ──────
12
+ test:
13
+ name: Run Test Suite
14
+ uses: ./.github/workflows/app-test.yml
15
+
16
+ # ── 2. Build the wheel and sdist ────────────────────────────────────────
17
+ build:
18
+ name: Build Distribution
19
+ needs: test
20
+ runs-on: ubuntu-latest
21
+
22
+ steps:
23
+ - name: Checkout
24
+ uses: actions/checkout@v4
25
+
26
+ - name: Setup Python
27
+ uses: actions/setup-python@v5
28
+ with:
29
+ python-version: "3.11"
30
+ cache: pip
31
+
32
+ - name: Install build tools
33
+ run: |
34
+ python -m pip install --upgrade pip
35
+ pip install build
36
+
37
+ - name: Build wheel and sdist
38
+ run: python -m build
39
+
40
+ - name: Upload distribution artifacts
41
+ uses: actions/upload-artifact@v4
42
+ with:
43
+ name: dist
44
+ path: dist/
45
+ retention-days: 7
46
+
47
+ # ── 3. Publish to PyPI ──────────────────────────────────────────────────
48
+ publish:
49
+ name: Publish to PyPI
50
+ needs: build
51
+ runs-on: ubuntu-latest
52
+
53
+ # Restrict to the production branch only — belt-and-suspenders guard
54
+ # so an accidental workflow_dispatch on dev cannot publish.
55
+ if: github.ref == 'refs/heads/production'
56
+
57
+ # PyPI Trusted Publishing (OIDC) — no long-lived API token required.
58
+ # Configure at: https://pypi.org/manage/project/openframe-core/settings/publishing/
59
+ # Add a publisher with:
60
+ # Owner: <your GitHub org/user>
61
+ # Repo: openframe-core
62
+ # Workflow: python-build.yml
63
+ # Env: pypi
64
+ environment:
65
+ name: pypi
66
+ url: https://pypi.org/p/openframe-core
67
+
68
+ permissions:
69
+ id-token: write # required for OIDC trusted publishing
70
+
71
+ steps:
72
+ - name: Download distribution artifacts
73
+ uses: actions/download-artifact@v4
74
+ with:
75
+ name: dist
76
+ path: dist/
77
+
78
+ - name: Publish to PyPI
79
+ uses: pypa/gh-action-pypi-publish@release/v1
80
+ # No password needed when using OIDC trusted publishing.
81
+ # If you prefer an API token, uncomment the line below and set the
82
+ # PYPI_API_TOKEN secret in repo Settings → Secrets → Actions:
83
+ # with:
84
+ # password: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,218 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
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
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ # Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ # poetry.lock
109
+ # poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ # pdm.lock
116
+ # pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ # pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # Redis
135
+ *.rdb
136
+ *.aof
137
+ *.pid
138
+
139
+ # RabbitMQ
140
+ mnesia/
141
+ rabbitmq/
142
+ rabbitmq-data/
143
+
144
+ # ActiveMQ
145
+ activemq-data/
146
+
147
+ # SageMath parsed files
148
+ *.sage.py
149
+
150
+ # Environments
151
+ .env
152
+ .envrc
153
+ .venv
154
+ env/
155
+ venv/
156
+ ENV/
157
+ env.bak/
158
+ venv.bak/
159
+
160
+ # Spyder project settings
161
+ .spyderproject
162
+ .spyproject
163
+
164
+ # Rope project settings
165
+ .ropeproject
166
+
167
+ # mkdocs documentation
168
+ /site
169
+
170
+ # mypy
171
+ .mypy_cache/
172
+ .dmypy.json
173
+ dmypy.json
174
+
175
+ # Pyre type checker
176
+ .pyre/
177
+
178
+ # pytype static type analyzer
179
+ .pytype/
180
+
181
+ # Cython debug symbols
182
+ cython_debug/
183
+
184
+ # PyCharm
185
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
186
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
187
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
188
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
189
+ # .idea/
190
+
191
+ # Abstra
192
+ # Abstra is an AI-powered process automation framework.
193
+ # Ignore directories containing user credentials, local state, and settings.
194
+ # Learn more at https://abstra.io/docs
195
+ .abstra/
196
+
197
+ # Visual Studio Code
198
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
199
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
200
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
201
+ # you could uncomment the following to ignore the entire vscode folder
202
+ # .vscode/
203
+ # Temporary file for partial code execution
204
+ tempCodeRunnerFile.py
205
+
206
+ # Ruff stuff:
207
+ .ruff_cache/
208
+
209
+ # PyPI configuration file
210
+ .pypirc
211
+
212
+ # Marimo
213
+ marimo/_static/
214
+ marimo/_lsp/
215
+ __marimo__/
216
+
217
+ # Streamlit
218
+ .streamlit/secrets.toml
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 OpenFrame
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.