datex-studio-cli 0.5.0__tar.gz → 0.5.1__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.
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/.gitignore +6 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/PKG-INFO +1 -1
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/pyproject.toml +6 -1
- datex_studio_cli-0.5.1/scripts/datadog_errors.py +275 -0
- datex_studio_cli-0.5.1/scripts/wavelength_query.py +428 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/__init__.py +1 -1
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/cli.py +58 -2
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/explore.py +5 -30
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/reset.py +1 -0
- datex_studio_cli-0.5.1/src/dxs/commands/skills.py +442 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/api/endpoints.py +15 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/404/index.html +1 -1
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/404.html +1 -1
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/design/capture/index.html +1 -1
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/design/capture/index.txt +1 -1
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/design/index.html +1 -1
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/design/index.txt +1 -1
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/index.html +1 -1
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/index.txt +1 -1
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/.dockerignore +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/.github/actionlint.yaml +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/.github/workflows/build-image.yml +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/.github/workflows/ci.yml +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/.github/workflows/promote-prod.yml +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/.github/workflows/release.yml +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/CONTEXT.md +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/README.md +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/otel/.env.example +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/otel/Dockerfile +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/otel/README.md +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/otel/apply-local-cache.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/otel/collector-config.yaml +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/otel/docker-compose.yml +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/otel/local-test-settings.json +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/otel/remote-settings.json +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/report-creator.skill +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/scripts/analyze_corpus.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/scripts/generate_rdlx_schema.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/__main__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/api.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/auth.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/branch.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/branch_commit_guard.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/cascade.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/config.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/configuration.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/crm.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/crm_delivery.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/crm_time.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/datasource.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/devops.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/document.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/endpoint.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/env.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/function.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/init.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/marketplace.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/ng/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/ng/_common.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/ng/api.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/ng/create.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/ng/data.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/ng/pack.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/ng/preview.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/odata.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/organization.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/proxy.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/reference.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/release_notes.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/repo.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/report/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/report/add_cmds.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/report/api.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/report/batch.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/report/create.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/report/data.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/report/dataset.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/report/edit.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/report/folder.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/report/preview.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/report/schema_cmds.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/schema.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/servicepack.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/source.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/studio.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/telemetry.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/user.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/commands/validation_report.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/context.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/agent_browser.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/api/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/api/app_config.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/api/client.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/api/metadata_models.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/api/models.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/api/reference_graph.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/api/replacements.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/auth/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/auth/datex_tenant.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/auth/decorators.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/auth/msal_client.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/auth/tenants.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/auth/token_cache.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/cache.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/datasource/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/datasource/flow_generator.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/datasource/flow_models.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/datasource/flow_shape.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/datasource/generator.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/datasource/models.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/datasource/parsers.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/datasource/resolver.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/datasource/type_def_parser.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/datasource/validator.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/designer/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/designer/flow_models.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/designer/models.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/designer/parsers.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/devops/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/devops/client.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/devops/helpers.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/devops/models.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/dynamics/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/dynamics/client.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/dynamics/html.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/dynamics/metadata_cache.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/dynamics/pagination.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/dynamics/resolvers.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/dynamics/time_entry.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/footprint/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/footprint/client.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/footprint/edmx_parser.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/footprint/metadata.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/function/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/function/generator.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/function/models.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/function/validator.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/graph.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/onboarding.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/output/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/output/csv_fmt.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/output/formatter.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/output/json_fmt.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/output/redaction.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/output/yaml_fmt.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/release_notes.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/responses.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/telemetry/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/telemetry/config.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/telemetry/identity.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/telemetry/recorder.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/telemetry/scrubber.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/core/telemetry/sender.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/models/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/ng/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/ng/folder.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/ng/manifest.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/ng/mocks.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/ng/preview.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/ng/scaffold.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/ng/serve_lock.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/py.typed +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/datasource_binding.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/engine.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/field_parser.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/folder.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/manifest.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/models.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/preview.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/preview_arjs.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/schema.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/svg_renderer.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/templates/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/templates/bill_of_lading.rdlx-json +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/templates/shipping_label.rdlx-json +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/validate_arjs.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/validator.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/report/wrapper.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/utils/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/utils/click_options.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/utils/clipboard.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/utils/config.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/utils/errors.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/utils/filtering.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/utils/image.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/utils/paths.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/utils/resolvers.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/utils/responses.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/utils/restricted.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/utils/sorting.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/utils/update_check.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/utils/versioning.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/__init__.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/app.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/design.py +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/proxy_app.py +0 -0
- {datex_studio_cli-0.5.0/src/dxs/web/static/_next/static/hfb4z29yVHQge-muP6roV → datex_studio_cli-0.5.1/src/dxs/web/static/_next/static/W6-87g3VtSLhTM2G0U3r1}/_buildManifest.js +0 -0
- {datex_studio_cli-0.5.0/src/dxs/web/static/_next/static/hfb4z29yVHQge-muP6roV → datex_studio_cli-0.5.1/src/dxs/web/static/_next/static/W6-87g3VtSLhTM2G0U3r1}/_ssgManifest.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/0b24cca5-c1e1c8810348f107.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/255-102f2e5b2e3dc2ef.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/4bd1b696-c023c6e3521b1417.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/538-b06224e65f71c9a1.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/697-0e000ab410d9f470.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/871-1acacdb7b4022abf.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/8b8f67fc-6295949a4b5485a4.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/909-c88abba3cf0caec3.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/app/_not-found/page-e3c660196c244183.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/app/design/capture/page-c083dc9f01f32a04.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/app/design/page-689cd5b9e1d9a74e.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/app/layout-cec86f90e385371d.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/app/page-f0380b0f29983264.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/framework-de98b93a850cfc71.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/main-0f18f91200dac003.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/main-app-694cf3568b6c9fa9.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/pages/_app-7d307437aca18ad4.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/pages/_error-cb2a52f75f2162e2.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/chunks/webpack-2b297ada5306c17f.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/_next/static/css/360c657de5e04df8.css +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/render-cli.js +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/report-preview.html +0 -0
- {datex_studio_cli-0.5.0 → datex_studio_cli-0.5.1}/src/dxs/web/static/report-validate.html +0 -0
|
@@ -105,3 +105,9 @@ test-preview.svg
|
|
|
105
105
|
|
|
106
106
|
# Live auth matrix config (real accounts)
|
|
107
107
|
tests/live/accounts.local.json
|
|
108
|
+
|
|
109
|
+
# Project-scope `dxs skills` install artifacts (.claude/skills is above).
|
|
110
|
+
# Canonical copies, the codex symlink tree, and the install record.
|
|
111
|
+
.agents/
|
|
112
|
+
.codex/
|
|
113
|
+
skills-lock.json
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: datex-studio-cli
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: CLI for Datex Studio low-code platform, designed for LLM-based AI agents
|
|
5
5
|
Project-URL: Homepage, https://github.com/datex/datex-studio-cli
|
|
6
6
|
Project-URL: Documentation, https://github.com/datex/datex-studio-cli
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "datex-studio-cli"
|
|
7
|
-
version = "0.5.
|
|
7
|
+
version = "0.5.1"
|
|
8
8
|
description = "CLI for Datex Studio low-code platform, designed for LLM-based AI agents"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -149,6 +149,10 @@ ignore_missing_imports = true
|
|
|
149
149
|
module = ["fastapi.*", "uvicorn.*"]
|
|
150
150
|
ignore_missing_imports = true
|
|
151
151
|
|
|
152
|
+
[[tool.mypy.overrides]]
|
|
153
|
+
module = ["pyodbc"]
|
|
154
|
+
ignore_missing_imports = true
|
|
155
|
+
|
|
152
156
|
[tool.pytest.ini_options]
|
|
153
157
|
testpaths = ["tests"]
|
|
154
158
|
python_files = ["test_*.py"]
|
|
@@ -160,6 +164,7 @@ markers = [
|
|
|
160
164
|
"real_auth_state: exercise real auth state (no injected DXS_ACCESS_TOKEN; the variable is scrubbed)",
|
|
161
165
|
"telemetry_live: run without the suite-wide DXS_TELEMETRY=0 kill-switch",
|
|
162
166
|
"live_auth: sign in against real Entra tenants (opt-in; needs DXS_LIVE_AUTH=1 + a human)",
|
|
167
|
+
"mssql: integration tests against a throwaway SQL Server container (opt-in; needs DXS_MSSQL_TEST=1)",
|
|
163
168
|
]
|
|
164
169
|
|
|
165
170
|
[tool.coverage.run]
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# /// script
|
|
2
|
+
# requires-python = ">=3.10"
|
|
3
|
+
# dependencies = ["httpx", "python-dotenv"]
|
|
4
|
+
# ///
|
|
5
|
+
"""Pull recent CLI error events from Datadog Logs for investigation.
|
|
6
|
+
|
|
7
|
+
Queries the Datadog Logs Search API for ``service:dxs-cli status:error`` (the
|
|
8
|
+
telemetry forwarder's shape — see docs/telemetry-datadog-mapping.md) and prints
|
|
9
|
+
either a summary grouped by command + error code, or the raw events.
|
|
10
|
+
|
|
11
|
+
Credentials come from the project ``.env``: DATADOG_API_KEY, DATADOG_APP_KEY,
|
|
12
|
+
DATADOG_SITE (e.g. ``us3.datadoghq.com``).
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
uv run scripts/datadog_errors.py # last 24h, summary
|
|
16
|
+
uv run scripts/datadog_errors.py --since 7d # last 7 days
|
|
17
|
+
uv run scripts/datadog_errors.py --since 7d --list # one line per event
|
|
18
|
+
uv run scripts/datadog_errors.py --code DXS-API-001 --detail # full stacks
|
|
19
|
+
uv run scripts/datadog_errors.py --command source --version 0.5.0 -f json
|
|
20
|
+
uv run scripts/datadog_errors.py -q 'usr.email:*@datexcorp.com' # extra filter
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import argparse
|
|
26
|
+
import json
|
|
27
|
+
import os
|
|
28
|
+
import re
|
|
29
|
+
import sys
|
|
30
|
+
import time
|
|
31
|
+
from collections import Counter, defaultdict
|
|
32
|
+
from datetime import datetime, timedelta, timezone
|
|
33
|
+
from pathlib import Path
|
|
34
|
+
from typing import Any
|
|
35
|
+
|
|
36
|
+
SUMMARY_FIELDS = (
|
|
37
|
+
"ts",
|
|
38
|
+
"command",
|
|
39
|
+
"error_code",
|
|
40
|
+
"error_class",
|
|
41
|
+
"error_message",
|
|
42
|
+
"cli_version",
|
|
43
|
+
"api_target",
|
|
44
|
+
"env",
|
|
45
|
+
"usr_email",
|
|
46
|
+
"org",
|
|
47
|
+
"os",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def parse_since(value: str) -> timedelta:
|
|
52
|
+
m = re.fullmatch(r"(\d+)([mhd])", value.strip())
|
|
53
|
+
if not m:
|
|
54
|
+
raise argparse.ArgumentTypeError("expected like 30m, 6h, 7d")
|
|
55
|
+
n, unit = int(m.group(1)), m.group(2)
|
|
56
|
+
return timedelta(**{{"m": "minutes", "h": "hours", "d": "days"}[unit]: n})
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def build_query(args: argparse.Namespace) -> str:
|
|
60
|
+
parts = [f"service:{args.service}", "status:error"]
|
|
61
|
+
if args.env:
|
|
62
|
+
parts.append(f"env:{args.env}")
|
|
63
|
+
if args.api_target:
|
|
64
|
+
parts.append(f"@api_target:{args.api_target}")
|
|
65
|
+
if args.code:
|
|
66
|
+
parts.append(f"@error_code:{args.code}")
|
|
67
|
+
if args.command:
|
|
68
|
+
parts.append(f'@command:"{args.command}"')
|
|
69
|
+
if args.version:
|
|
70
|
+
parts.append(f"@version:{args.version}")
|
|
71
|
+
if args.query:
|
|
72
|
+
parts.append(f"({args.query})")
|
|
73
|
+
return " ".join(parts)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def fetch_events(
|
|
77
|
+
site: str, api_key: str, app_key: str, query: str, since: timedelta, limit: int
|
|
78
|
+
) -> list[dict[str, Any]]:
|
|
79
|
+
import httpx
|
|
80
|
+
|
|
81
|
+
now = datetime.now(timezone.utc)
|
|
82
|
+
body: dict[str, Any] = {
|
|
83
|
+
"filter": {
|
|
84
|
+
"query": query,
|
|
85
|
+
"from": (now - since).isoformat(),
|
|
86
|
+
"to": now.isoformat(),
|
|
87
|
+
},
|
|
88
|
+
"sort": "-timestamp",
|
|
89
|
+
"page": {"limit": min(limit, 1000)},
|
|
90
|
+
}
|
|
91
|
+
headers = {
|
|
92
|
+
"DD-API-KEY": api_key,
|
|
93
|
+
"DD-APPLICATION-KEY": app_key,
|
|
94
|
+
"Content-Type": "application/json",
|
|
95
|
+
}
|
|
96
|
+
events: list[dict[str, Any]] = []
|
|
97
|
+
retries = 0
|
|
98
|
+
with httpx.Client(base_url=f"https://api.{site}", headers=headers, timeout=30) as client:
|
|
99
|
+
while True:
|
|
100
|
+
resp = client.post("/api/v2/logs/events/search", json=body)
|
|
101
|
+
if resp.status_code == 429 and retries < 3:
|
|
102
|
+
wait = int(
|
|
103
|
+
resp.headers.get("Retry-After") or resp.headers.get("X-RateLimit-Reset") or 5
|
|
104
|
+
)
|
|
105
|
+
print(f"rate limited; retrying in {wait}s", file=sys.stderr)
|
|
106
|
+
time.sleep(wait)
|
|
107
|
+
retries += 1
|
|
108
|
+
continue
|
|
109
|
+
if resp.status_code != 200:
|
|
110
|
+
print(f"Datadog API {resp.status_code}: {resp.text[:500]}", file=sys.stderr)
|
|
111
|
+
sys.exit(1)
|
|
112
|
+
payload = resp.json()
|
|
113
|
+
events.extend(payload.get("data", []))
|
|
114
|
+
cursor = payload.get("meta", {}).get("page", {}).get("after")
|
|
115
|
+
if not cursor or len(events) >= limit:
|
|
116
|
+
break
|
|
117
|
+
body["page"]["cursor"] = cursor
|
|
118
|
+
return events[:limit]
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def full_command(group: str | None, argv: Any) -> str | None:
|
|
122
|
+
"""`command` is only the Click group (e.g. `configuration`); recover the
|
|
123
|
+
subcommand path from argv: the bare-word tokens that follow the group."""
|
|
124
|
+
if not group or not isinstance(argv, list):
|
|
125
|
+
return group
|
|
126
|
+
try:
|
|
127
|
+
i = argv.index(group)
|
|
128
|
+
except ValueError:
|
|
129
|
+
return group
|
|
130
|
+
words = [group]
|
|
131
|
+
for tok in argv[i + 1 : i + 3]:
|
|
132
|
+
if isinstance(tok, str) and re.fullmatch(r"[a-z][a-z-]*", tok):
|
|
133
|
+
words.append(tok)
|
|
134
|
+
else:
|
|
135
|
+
break
|
|
136
|
+
return " ".join(words)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def flatten(event: dict[str, Any]) -> dict[str, Any]:
|
|
140
|
+
"""Reduce a Datadog log event to the attributes worth reading."""
|
|
141
|
+
attrs = event.get("attributes", {})
|
|
142
|
+
custom = attrs.get("attributes", {}) # user attributes live one level down
|
|
143
|
+
tags = dict(t.split(":", 1) for t in attrs.get("tags", []) if ":" in t)
|
|
144
|
+
usr = custom.get("usr", {}) or {}
|
|
145
|
+
err = custom.get("error", {}) or {}
|
|
146
|
+
return {
|
|
147
|
+
"id": event.get("id"),
|
|
148
|
+
"ts": attrs.get("timestamp"),
|
|
149
|
+
"message": attrs.get("message"),
|
|
150
|
+
"command": full_command(custom.get("command"), custom.get("argv")),
|
|
151
|
+
"argv": custom.get("argv"),
|
|
152
|
+
"error_code": custom.get("error_code") or tags.get("error_code"),
|
|
153
|
+
"error_class": custom.get("error_class") or err.get("kind"),
|
|
154
|
+
"error_message": custom.get("error_message") or err.get("message"),
|
|
155
|
+
"error_stack": custom.get("error_stack") or err.get("stack"),
|
|
156
|
+
"exit_code": custom.get("exit_code"),
|
|
157
|
+
"duration_ms": custom.get("duration_ms"),
|
|
158
|
+
"cli_version": custom.get("version") or tags.get("version"),
|
|
159
|
+
"org": custom.get("datex_org_name") or tags.get("org"),
|
|
160
|
+
"python_version": custom.get("python_version"),
|
|
161
|
+
"os": custom.get("os", {}).get("name")
|
|
162
|
+
if isinstance(custom.get("os"), dict)
|
|
163
|
+
else custom.get("os"),
|
|
164
|
+
"os_release": custom.get("os_release"),
|
|
165
|
+
"api_target": custom.get("api_target") or tags.get("api_target"),
|
|
166
|
+
"env": tags.get("env"),
|
|
167
|
+
"usr_id": usr.get("id"),
|
|
168
|
+
"usr_email": usr.get("email"),
|
|
169
|
+
"usr_name": usr.get("name"),
|
|
170
|
+
"session_id": (custom.get("session") or {}).get("id"),
|
|
171
|
+
"install_id": custom.get("install_id"),
|
|
172
|
+
"ctx_branch_id": custom.get("ctx_branch_id"),
|
|
173
|
+
"ctx_org": custom.get("ctx_org"),
|
|
174
|
+
"ctx_env": custom.get("ctx_env"),
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def print_summary(rows: list[dict[str, Any]]) -> None:
|
|
179
|
+
if not rows:
|
|
180
|
+
print("No matching error events.")
|
|
181
|
+
return
|
|
182
|
+
groups: dict[tuple[str, str, str], list[dict[str, Any]]] = defaultdict(list)
|
|
183
|
+
for r in rows:
|
|
184
|
+
groups[(r["command"] or "?", r["error_code"] or "-", r["error_class"] or "?")].append(r)
|
|
185
|
+
print(f"{len(rows)} error events, {len(groups)} distinct (command, code, class)\n")
|
|
186
|
+
print(f"{'count':>5} {'command':<28} {'code':<14} {'class':<24} sample message")
|
|
187
|
+
for key, grp in sorted(groups.items(), key=lambda kv: -len(kv[1])):
|
|
188
|
+
cmd, code, cls = key
|
|
189
|
+
msg = (grp[0]["error_message"] or "")[:80].replace("\n", " ")
|
|
190
|
+
print(f"{len(grp):>5} {cmd:<28} {code:<14} {cls:<24} {msg}")
|
|
191
|
+
users = Counter(r["usr_email"] or r["usr_name"] or "?" for r in grp)
|
|
192
|
+
versions = Counter(r["cli_version"] or "?" for r in grp)
|
|
193
|
+
print(
|
|
194
|
+
f" last={grp[0]['ts']} users={dict(users.most_common(3))}"
|
|
195
|
+
f" versions={dict(versions.most_common(3))}"
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def print_list(rows: list[dict[str, Any]]) -> None:
|
|
200
|
+
for r in rows:
|
|
201
|
+
msg = (r["error_message"] or "")[:100].replace("\n", " ")
|
|
202
|
+
print(
|
|
203
|
+
f"{r['ts']} {r['cli_version'] or '?':<8} {r['usr_email'] or r['usr_name'] or '?':<32}"
|
|
204
|
+
f" {r['command'] or '?':<28} {r['error_code'] or '-':<14} {msg}"
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def print_detail(rows: list[dict[str, Any]]) -> None:
|
|
209
|
+
for r in rows:
|
|
210
|
+
print("=" * 100)
|
|
211
|
+
for k in SUMMARY_FIELDS + ("argv", "ctx_branch_id", "ctx_org", "session_id", "id"):
|
|
212
|
+
if r.get(k) is not None:
|
|
213
|
+
print(f"{k:<14} {r[k]}")
|
|
214
|
+
if r.get("error_stack"):
|
|
215
|
+
print("--- stack ---")
|
|
216
|
+
print(r["error_stack"])
|
|
217
|
+
print("=" * 100)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def main(argv: list[str] | None = None) -> None:
|
|
221
|
+
p = argparse.ArgumentParser(
|
|
222
|
+
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
|
|
223
|
+
)
|
|
224
|
+
p.add_argument(
|
|
225
|
+
"--since",
|
|
226
|
+
type=parse_since,
|
|
227
|
+
default="24h",
|
|
228
|
+
help="lookback window, e.g. 30m, 6h, 7d (default 24h)",
|
|
229
|
+
)
|
|
230
|
+
p.add_argument("--service", default="dxs-cli", help="Datadog service tag (default dxs-cli)")
|
|
231
|
+
p.add_argument("--env", help="ddtag env: staging|prod|local (which Quartermaster received it)")
|
|
232
|
+
p.add_argument("--api-target", help="dev|qa|prod|default (which Datex environment the CLI hit)")
|
|
233
|
+
p.add_argument("--code", help="filter by DXS-* error code")
|
|
234
|
+
p.add_argument(
|
|
235
|
+
"--command", help="filter by Click group, e.g. configuration (subcommand is only in argv)"
|
|
236
|
+
)
|
|
237
|
+
p.add_argument("--version", help="filter by cli_version")
|
|
238
|
+
p.add_argument("-q", "--query", help="extra raw Datadog log query ANDed onto the filter")
|
|
239
|
+
p.add_argument("-n", "--limit", type=int, default=500, help="max events to fetch (default 500)")
|
|
240
|
+
mode = p.add_mutually_exclusive_group()
|
|
241
|
+
mode.add_argument("--list", action="store_true", help="one line per event")
|
|
242
|
+
mode.add_argument("--detail", action="store_true", help="every field + stack per event")
|
|
243
|
+
p.add_argument("-f", "--format", choices=["text", "json"], default="text")
|
|
244
|
+
p.add_argument("--show-query", action="store_true", help="print the Datadog query and exit")
|
|
245
|
+
args = p.parse_args(argv)
|
|
246
|
+
|
|
247
|
+
from dotenv import load_dotenv
|
|
248
|
+
|
|
249
|
+
load_dotenv(Path(__file__).resolve().parent.parent / ".env")
|
|
250
|
+
api_key, app_key = os.environ.get("DATADOG_API_KEY"), os.environ.get("DATADOG_APP_KEY")
|
|
251
|
+
site = os.environ.get("DATADOG_SITE", "datadoghq.com")
|
|
252
|
+
if not api_key or not app_key:
|
|
253
|
+
print("DATADOG_API_KEY and DATADOG_APP_KEY must be set (expected in .env)", file=sys.stderr)
|
|
254
|
+
sys.exit(1)
|
|
255
|
+
|
|
256
|
+
query = build_query(args)
|
|
257
|
+
if args.show_query:
|
|
258
|
+
print(query)
|
|
259
|
+
return
|
|
260
|
+
print(f"query: {query} window: last {args.since}", file=sys.stderr)
|
|
261
|
+
|
|
262
|
+
rows = [flatten(e) for e in fetch_events(site, api_key, app_key, query, args.since, args.limit)]
|
|
263
|
+
if args.format == "json":
|
|
264
|
+
json.dump(rows, sys.stdout, indent=2, default=str)
|
|
265
|
+
print()
|
|
266
|
+
elif args.detail:
|
|
267
|
+
print_detail(rows)
|
|
268
|
+
elif args.list:
|
|
269
|
+
print_list(rows)
|
|
270
|
+
else:
|
|
271
|
+
print_summary(rows)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
if __name__ == "__main__":
|
|
275
|
+
main()
|