pbs-client 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 (47) hide show
  1. pbs_client-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +66 -0
  2. pbs_client-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  3. pbs_client-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +32 -0
  4. pbs_client-0.1.0/.github/ISSUE_TEMPLATE/not_working.yml +65 -0
  5. pbs_client-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +9 -0
  6. pbs_client-0.1.0/.github/release-drafter.yml +31 -0
  7. pbs_client-0.1.0/.github/workflows/ci.yml +10 -0
  8. pbs_client-0.1.0/.github/workflows/merge.yml +10 -0
  9. pbs_client-0.1.0/.github/workflows/publish.yml +19 -0
  10. pbs_client-0.1.0/.gitignore +147 -0
  11. pbs_client-0.1.0/.importlinter +14 -0
  12. pbs_client-0.1.0/CONTRIBUTING.md +27 -0
  13. pbs_client-0.1.0/NOTICE +6 -0
  14. pbs_client-0.1.0/PKG-INFO +65 -0
  15. pbs_client-0.1.0/README.md +45 -0
  16. pbs_client-0.1.0/pyproject.toml +52 -0
  17. pbs_client-0.1.0/src/pbs_client/__init__.py +5 -0
  18. pbs_client-0.1.0/src/pbs_client/cli/__init__.py +6 -0
  19. pbs_client-0.1.0/src/pbs_client/cli/main.py +127 -0
  20. pbs_client-0.1.0/src/pbs_client/config.py +107 -0
  21. pbs_client-0.1.0/src/pbs_client/db/__init__.py +27 -0
  22. pbs_client-0.1.0/src/pbs_client/db/engine.py +37 -0
  23. pbs_client-0.1.0/src/pbs_client/db/model/__init__.py +83 -0
  24. pbs_client-0.1.0/src/pbs_client/db/model/base.py +18 -0
  25. pbs_client-0.1.0/src/pbs_client/db/model/core.py +285 -0
  26. pbs_client-0.1.0/src/pbs_client/db/model/items.py +315 -0
  27. pbs_client-0.1.0/src/pbs_client/db/model/pricing.py +64 -0
  28. pbs_client-0.1.0/src/pbs_client/db/model/relationships.py +193 -0
  29. pbs_client-0.1.0/src/pbs_client/db/models.py +3 -0
  30. pbs_client-0.1.0/src/pbs_client/db/schema.py +190 -0
  31. pbs_client-0.1.0/src/pbs_client/db/state.py +41 -0
  32. pbs_client-0.1.0/src/pbs_client/errors.py +43 -0
  33. pbs_client-0.1.0/src/pbs_client/http/__init__.py +6 -0
  34. pbs_client-0.1.0/src/pbs_client/http/client.py +221 -0
  35. pbs_client-0.1.0/src/pbs_client/query/__init__.py +30 -0
  36. pbs_client-0.1.0/src/pbs_client/query/service.py +167 -0
  37. pbs_client-0.1.0/src/pbs_client/sync/__init__.py +6 -0
  38. pbs_client-0.1.0/src/pbs_client/sync/orchestrator.py +198 -0
  39. pbs_client-0.1.0/tests/conftest.py +22 -0
  40. pbs_client-0.1.0/tests/fixtures/items-page-1.json +36 -0
  41. pbs_client-0.1.0/tests/fixtures/schedules-page-1.json +22 -0
  42. pbs_client-0.1.0/tests/test_config.py +53 -0
  43. pbs_client-0.1.0/tests/test_http.py +72 -0
  44. pbs_client-0.1.0/tests/test_query.py +39 -0
  45. pbs_client-0.1.0/tests/test_schema.py +32 -0
  46. pbs_client-0.1.0/tests/test_sync.py +92 -0
  47. pbs_client-0.1.0/uv.lock +641 -0
@@ -0,0 +1,66 @@
1
+ name: "🐞 Bug Report"
2
+ description: Report a reproducible bug.
3
+ type: "Bug"
4
+ body:
5
+ - type: checkboxes
6
+ attributes:
7
+ label: Pre-flight
8
+ options:
9
+ - label: I searched existing issues and this is not a duplicate.
10
+ required: true
11
+
12
+ - type: textarea
13
+ id: summary
14
+ attributes:
15
+ label: Summary
16
+ description: One or two sentences describing the bug.
17
+ validations:
18
+ required: true
19
+
20
+ - type: textarea
21
+ id: reproduction
22
+ attributes:
23
+ label: Reproduction
24
+ description: Steps and/or a minimal code example that reproduces the issue. Wrap code in triple backticks.
25
+ placeholder: |
26
+ 1. Import X and call Y with Z
27
+ 2. Observe error
28
+
29
+ ```python
30
+ # minimal example
31
+ ```
32
+ validations:
33
+ required: true
34
+
35
+ - type: textarea
36
+ id: actual
37
+ attributes:
38
+ label: Actual behaviour
39
+ validations:
40
+ required: true
41
+
42
+ - type: textarea
43
+ id: expected
44
+ attributes:
45
+ label: Expected behaviour
46
+ validations:
47
+ required: true
48
+
49
+ - type: textarea
50
+ id: logs
51
+ attributes:
52
+ label: Error output
53
+ description: Full traceback if applicable. Formatted automatically.
54
+ render: python-traceback
55
+
56
+ - type: textarea
57
+ id: system
58
+ attributes:
59
+ label: System info
60
+ description: |
61
+ Run this in your environment and paste the output:
62
+
63
+ ```shell
64
+ python <(curl -s https://raw.githubusercontent.com/AustralianCancerDataNetwork/cava-devops/main/scripts/cava_system_info.py)
65
+ ```
66
+ render: shell
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Discussions
4
+ url: https://github.com/orgs/AustralianCancerDataNetwork/discussions
5
+ about: Questions and general discussion about the CAVA stack.
@@ -0,0 +1,32 @@
1
+ name: "🚀 Feature Request"
2
+ description: Propose a new feature or enhancement.
3
+ type: "Feature"
4
+ body:
5
+ - type: checkboxes
6
+ attributes:
7
+ label: Pre-flight
8
+ options:
9
+ - label: I searched existing issues and this has not been requested before.
10
+ required: true
11
+
12
+ - type: textarea
13
+ id: problem
14
+ attributes:
15
+ label: Problem or motivation
16
+ description: What are you trying to do that you currently cannot?
17
+ validations:
18
+ required: true
19
+
20
+ - type: textarea
21
+ id: proposal
22
+ attributes:
23
+ label: Proposed solution
24
+ description: How would you like this to work?
25
+ validations:
26
+ required: true
27
+
28
+ - type: textarea
29
+ id: alternatives
30
+ attributes:
31
+ label: Alternatives considered
32
+ description: Other approaches you considered and why you ruled them out.
@@ -0,0 +1,65 @@
1
+ name: "❗ Something is not working"
2
+ description: Something behaves unexpectedly but you are not sure if it is a bug.
3
+ body:
4
+ - type: checkboxes
5
+ attributes:
6
+ label: Pre-flight
7
+ options:
8
+ - label: I searched existing issues for this problem.
9
+ required: true
10
+
11
+ - type: textarea
12
+ id: summary
13
+ attributes:
14
+ label: Problem summary
15
+ description: 1-2 sentences describing what is not working.
16
+ validations:
17
+ required: true
18
+
19
+ - type: textarea
20
+ id: reproduction
21
+ attributes:
22
+ label: Reproduction
23
+ description: Steps and/or a minimal code example. Wrap code in triple backticks.
24
+ placeholder: |
25
+ 1. Import X and call Y with Z
26
+ 2. Observe unexpected behaviour
27
+
28
+ ```python
29
+ # minimal example
30
+ ```
31
+ validations:
32
+ required: true
33
+
34
+ - type: textarea
35
+ id: actual
36
+ attributes:
37
+ label: Actual outcome
38
+ validations:
39
+ required: true
40
+
41
+ - type: textarea
42
+ id: expected
43
+ attributes:
44
+ label: Expected outcome
45
+ validations:
46
+ required: true
47
+
48
+ - type: textarea
49
+ id: logs
50
+ attributes:
51
+ label: Error messages
52
+ description: Full traceback if applicable. Formatted automatically.
53
+ render: python-traceback
54
+
55
+ - type: textarea
56
+ id: system
57
+ attributes:
58
+ label: System info
59
+ description: |
60
+ Run this in your environment and paste the output:
61
+
62
+ ```shell
63
+ python <(curl -s https://raw.githubusercontent.com/AustralianCancerDataNetwork/cava-devops/main/scripts/cava_system_info.py)
64
+ ```
65
+ render: shell
@@ -0,0 +1,9 @@
1
+ ## Summary
2
+
3
+ <!-- What does this PR do? This text becomes the changelog entry — write it for a reader who will see it months from now, not for the reviewer reading the diff. Leave blank for chore PRs. -->
4
+
5
+ ## Checklist
6
+
7
+ - [ ] Applied exactly one label (`breaking`, `feature`, `fix`, `dependencies`, or `chore`)
8
+ - [ ] Tests pass locally (`uv run pytest -q`)
9
+ - [ ] Lint passes (`uv run ruff check .`)
@@ -0,0 +1,31 @@
1
+ name-template: 'v$RESOLVED_VERSION'
2
+ tag-template: 'v$RESOLVED_VERSION'
3
+ commitish: main
4
+
5
+ categories:
6
+ - title: Breaking Changes
7
+ labels: ['breaking']
8
+ - title: Features
9
+ labels: ['feature']
10
+ - title: Fixes
11
+ labels: ['fix']
12
+ - title: Dependencies
13
+ labels: ['dependencies']
14
+
15
+ template: |
16
+ $CHANGES
17
+
18
+ change-template: '- **$TITLE** (#$NUMBER) @$AUTHOR'
19
+
20
+ version-resolver:
21
+ major:
22
+ labels: ['breaking']
23
+ minor:
24
+ labels: ['feature']
25
+ patch:
26
+ labels: ['fix', 'dependencies']
27
+ default: patch
28
+
29
+ exclude-labels: ['chore']
30
+
31
+ autolabeler: []
@@ -0,0 +1,10 @@
1
+ name: CI
2
+ on:
3
+ pull_request:
4
+ branches: [main]
5
+ types: [opened, synchronize, reopened, labeled, unlabeled]
6
+ jobs:
7
+ label-gate:
8
+ uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/label-gate.yml@main
9
+ build-test:
10
+ uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/build-test.yml@main
@@ -0,0 +1,10 @@
1
+ name: Release Update
2
+ on:
3
+ pull_request:
4
+ types: [closed]
5
+ branches: [main]
6
+ jobs:
7
+ draft:
8
+ if: github.event.pull_request.merged == true
9
+ uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/release-drafter.yml@main
10
+ secrets: inherit
@@ -0,0 +1,19 @@
1
+ name: Publish
2
+ on:
3
+ push:
4
+ tags: ['v*']
5
+ jobs:
6
+ build:
7
+ uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/publish.yml@main
8
+ publish:
9
+ needs: build
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ id-token: write
13
+ environment:
14
+ name: pypi
15
+ url: https://pypi.org/p/pbs-client
16
+ steps:
17
+ - uses: actions/download-artifact@v4
18
+ with: { name: dist, path: dist/ }
19
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,147 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+ *.manifest
29
+ *.spec
30
+
31
+ # Installer logs
32
+ pip-log.txt
33
+ pip-delete-this-directory.txt
34
+
35
+ # Unit test / coverage reports
36
+ htmlcov/
37
+ .tox/
38
+ .nox/
39
+ .coverage
40
+ .coverage.*
41
+ .cache
42
+ nosetests.xml
43
+ coverage.xml
44
+ *.cover
45
+ *.py,cover
46
+ .hypothesis/
47
+ .pytest_cache/
48
+ cover/
49
+
50
+ # Translations
51
+ *.mo
52
+ *.pot
53
+
54
+ # Django stuff:
55
+ *.log
56
+ local_settings.py
57
+ db.sqlite3
58
+ db.sqlite3-journal
59
+
60
+ # Local PBS mirror (generated by `pbs-client sync`, not checked in)
61
+ *.db-journal
62
+
63
+ # Flask stuff:
64
+ instance/
65
+ .webassets-cache
66
+
67
+ # Scrapy stuff:
68
+ .scrapy
69
+
70
+ # Sphinx documentation
71
+ docs/_build/
72
+
73
+ # PyBuilder
74
+ .pybuilder/
75
+ target/
76
+
77
+ # Jupyter Notebook
78
+ .ipynb_checkpoints
79
+
80
+ # IPython
81
+ profile_default/
82
+ ipython_config.py
83
+
84
+
85
+ .pdm.toml
86
+ .pdm-python
87
+ .pdm-build/
88
+
89
+ __pypackages__/
90
+
91
+ # Celery stuff
92
+ celerybeat-schedule
93
+ celerybeat.pid
94
+
95
+ # SageMath parsed files
96
+ *.sage.py
97
+
98
+ # Environments
99
+ .env
100
+ .venv
101
+ env/
102
+ venv/
103
+ ENV/
104
+ env.bak/
105
+ venv.bak/
106
+
107
+ # Spyder project settings
108
+ .spyderproject
109
+ .spyproject
110
+
111
+ # Rope project settings
112
+ .ropeproject
113
+
114
+ # mkdocs documentation
115
+ /site
116
+
117
+ # mypy
118
+ .mypy_cache/
119
+ .dmypy.json
120
+ dmypy.json
121
+
122
+ # ruff
123
+ .ruff_cache/
124
+
125
+ # Pyre type checker
126
+ .pyre/
127
+
128
+ # pytype static type analyzer
129
+ .pytype/
130
+
131
+ # Cython debug symbols
132
+ cython_debug/
133
+
134
+ oa_system_config.yaml
135
+ data/
136
+ .DS_Store
137
+ *.csv
138
+ _design/
139
+ .vscode/
140
+ old/
141
+ logs/
142
+ notebooks/
143
+ reference/
144
+ TODO.md
145
+ docker/
146
+ *.db
147
+ *.db.*
@@ -0,0 +1,14 @@
1
+ [importlinter]
2
+ root_package = pbs_client
3
+ include_external_packages = True
4
+
5
+ [importlinter:contract:pbs-client-layers]
6
+ name = pbs-client layers: sync sits on http+db, query sits on db only
7
+ type = layers
8
+ layers =
9
+ pbs_client.cli
10
+ pbs_client.sync
11
+ pbs_client.query
12
+ pbs_client.db
13
+ pbs_client.http
14
+
@@ -0,0 +1,27 @@
1
+ # Contributing
2
+
3
+ ## Development setup
4
+
5
+ ```bash
6
+ uv sync --all-extras --dev
7
+ uv run pytest -q
8
+ uv run ruff check .
9
+ ```
10
+
11
+ ## Opening a pull request
12
+
13
+ 1. Apply **exactly one** label before merging:
14
+
15
+ | Label | When to use |
16
+ |---|---|
17
+ | `breaking` | Public API change, backward-incompatible |
18
+ | `feature` | New functionality, backward-compatible |
19
+ | `fix` | Bug fix |
20
+ | `dependencies` | Dependency version update |
21
+ | `chore` | CI changes, refactoring, test additions, docs — anything that does not affect the public-facing package. Bypasses the label gate; excluded from the changelog and does not bump the version. |
22
+
23
+ 2. When merging (squash), write a clear extended description in the merge dialog. That text — not the PR's opening description — becomes the changelog entry for this change. Leave it blank for `chore` PRs.
24
+
25
+ ## Versioning and releases
26
+
27
+ Versions are derived from git tags; there is no version string in any source file. Releases are triggered by a maintainer publishing the standing draft release on the repository's Releases page. There is no automated commit-back to `main`.
@@ -0,0 +1,6 @@
1
+ PBS Public Data API copyright notice:
2
+
3
+ Permission is granted to use and redistribute this content, as long as all
4
+ copyright statements are retained. Permission is not granted to modify this
5
+ content.
6
+
@@ -0,0 +1,65 @@
1
+ Metadata-Version: 2.5
2
+ Name: pbs-client
3
+ Version: 0.1.0
4
+ Summary: Offline-first client and local mirror for the Australian PBS Public Data API v3
5
+ Author: Australian Cancer Data Network
6
+ License: MIT
7
+ License-File: NOTICE
8
+ Requires-Python: >=3.12
9
+ Requires-Dist: oa-configurator<2.0.0,>=1.2.1
10
+ Requires-Dist: pydantic<3.0,>=2.0
11
+ Requires-Dist: rich>=13.0
12
+ Requires-Dist: sqlalchemy>=2.0.45
13
+ Requires-Dist: typer>=0.12
14
+ Provides-Extra: dev
15
+ Requires-Dist: import-linter>=2.0; extra == 'dev'
16
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
17
+ Requires-Dist: pytest>=8.0; extra == 'dev'
18
+ Requires-Dist: ruff>=0.4; extra == 'dev'
19
+ Description-Content-Type: text/markdown
20
+
21
+ # pbs-client
22
+
23
+ `pbs-client` is an offline-first Python client and local SQLite mirror for the Australian PBS Public Data API v3. It mirrors all API resources, retains schedule history locally, and exposes small read helpers for item, restriction/indication, and ATC lookups.
24
+
25
+ ## Quick start
26
+
27
+ ```shell
28
+ uv sync --extra dev
29
+ uv run omop-config configure pbs_client
30
+ uv run pbs-client init-db
31
+ uv run pbs-client sync
32
+ ```
33
+
34
+ The package registers `PBSClientConfig` with `oa-configurator` under the
35
+ `pbs_client` tool name. The configuration wizard creates a `[tools.pbs_client]`
36
+ section and a named generic database entry (`pbs_db`) that can be shared with
37
+ downstream packages such as Groundworkers.
38
+
39
+ For a non-interactive local SQLite setup, the relevant stack configuration is:
40
+
41
+ ```toml
42
+ [connections.pbs_local]
43
+ dialect = "sqlite"
44
+ database_name = "/absolute/path/to/pbs_client.db"
45
+
46
+ [databases.pbs_db]
47
+ kind = "generic"
48
+ connection = "pbs_local"
49
+
50
+ [tools.pbs_client]
51
+ pbs_db = "pbs_db"
52
+ subscription_key = "your-subscription-key"
53
+ ```
54
+
55
+ Set `OA_CONFIG_PATH` before invoking the commands when using a config file
56
+ outside `~/.config/omop/config.toml`. The legacy `--db-path` option remains
57
+ available for local one-off runs and uses the `PBS_CLIENT_*` environment
58
+ variables for API settings.
59
+
60
+ The public API is deliberately rate limited to one request per twenty seconds. The client enforces that interval process-wide, including retries and page continuations. Tests use local fixtures and never call the API.
61
+
62
+ Configuration is normally read from `oa-configurator`. Direct library use still
63
+ supports `PBS_CLIENT_SUBSCRIPTION_KEY`, `PBS_CLIENT_DB_PATH`,
64
+ `PBS_CLIENT_BASE_URL`, and `PBS_CLIENT_RATE_LIMIT_SECONDS`. The database
65
+ defaults to `./pbs_client.db` only for that legacy environment-variable path.
@@ -0,0 +1,45 @@
1
+ # pbs-client
2
+
3
+ `pbs-client` is an offline-first Python client and local SQLite mirror for the Australian PBS Public Data API v3. It mirrors all API resources, retains schedule history locally, and exposes small read helpers for item, restriction/indication, and ATC lookups.
4
+
5
+ ## Quick start
6
+
7
+ ```shell
8
+ uv sync --extra dev
9
+ uv run omop-config configure pbs_client
10
+ uv run pbs-client init-db
11
+ uv run pbs-client sync
12
+ ```
13
+
14
+ The package registers `PBSClientConfig` with `oa-configurator` under the
15
+ `pbs_client` tool name. The configuration wizard creates a `[tools.pbs_client]`
16
+ section and a named generic database entry (`pbs_db`) that can be shared with
17
+ downstream packages such as Groundworkers.
18
+
19
+ For a non-interactive local SQLite setup, the relevant stack configuration is:
20
+
21
+ ```toml
22
+ [connections.pbs_local]
23
+ dialect = "sqlite"
24
+ database_name = "/absolute/path/to/pbs_client.db"
25
+
26
+ [databases.pbs_db]
27
+ kind = "generic"
28
+ connection = "pbs_local"
29
+
30
+ [tools.pbs_client]
31
+ pbs_db = "pbs_db"
32
+ subscription_key = "your-subscription-key"
33
+ ```
34
+
35
+ Set `OA_CONFIG_PATH` before invoking the commands when using a config file
36
+ outside `~/.config/omop/config.toml`. The legacy `--db-path` option remains
37
+ available for local one-off runs and uses the `PBS_CLIENT_*` environment
38
+ variables for API settings.
39
+
40
+ The public API is deliberately rate limited to one request per twenty seconds. The client enforces that interval process-wide, including retries and page continuations. Tests use local fixtures and never call the API.
41
+
42
+ Configuration is normally read from `oa-configurator`. Direct library use still
43
+ supports `PBS_CLIENT_SUBSCRIPTION_KEY`, `PBS_CLIENT_DB_PATH`,
44
+ `PBS_CLIENT_BASE_URL`, and `PBS_CLIENT_RATE_LIMIT_SECONDS`. The database
45
+ defaults to `./pbs_client.db` only for that legacy environment-variable path.
@@ -0,0 +1,52 @@
1
+ [project]
2
+ name = "pbs-client"
3
+ dynamic = ["version"]
4
+ description = "Offline-first client and local mirror for the Australian PBS Public Data API v3"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ authors = [{ name = "Australian Cancer Data Network" }]
8
+ license = { text = "MIT" }
9
+ dependencies = [
10
+ "oa-configurator>=1.2.1,<2.0.0",
11
+ "pydantic>=2.0,<3.0",
12
+ "sqlalchemy>=2.0.45",
13
+ "typer>=0.12",
14
+ "rich>=13.0",
15
+ ]
16
+
17
+ [project.optional-dependencies]
18
+ dev = [
19
+ "pytest>=8.0",
20
+ "pytest-cov>=4.0",
21
+ "ruff>=0.4",
22
+ "import-linter>=2.0",
23
+ ]
24
+
25
+ [project.scripts]
26
+ pbs-client = "pbs_client.cli:main"
27
+
28
+ [project.entry-points."omop.config"]
29
+ pbs_client = "pbs_client.config:PBSClientConfig"
30
+
31
+ [build-system]
32
+ requires = ["hatchling", "hatch-vcs"]
33
+ build-backend = "hatchling.build"
34
+
35
+ [tool.hatch.version]
36
+ source = "vcs"
37
+ raw-options = { tag_regex = '^v?(?P<version>[0-9]+\.[0-9]+\.[0-9]+)$' }
38
+ fallback-version = "0.1.0"
39
+
40
+ [tool.hatch.build.targets.wheel]
41
+ packages = ["src/pbs_client"]
42
+
43
+ [tool.uv]
44
+ cache-keys = [{ file = "pyproject.toml" }, { git = { commit = true, tags = true } }]
45
+
46
+ [tool.ruff]
47
+ line-length = 100
48
+ target-version = "py312"
49
+
50
+ [tool.pytest.ini_options]
51
+ testpaths = ["tests"]
52
+ addopts = "-q"
@@ -0,0 +1,5 @@
1
+ """Offline-first client and local mirror for the PBS Public Data API v3."""
2
+
3
+ from pbs_client.config import PBSClientConfig, PBSSettings, get_pbs_context
4
+
5
+ __all__ = ["PBSClientConfig", "PBSSettings", "get_pbs_context"]
@@ -0,0 +1,6 @@
1
+ """pbs-client command line entry point."""
2
+
3
+ from pbs_client.cli.main import app, main
4
+
5
+ __all__ = ["app", "main"]
6
+