open-data-products 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.
- open_data_products-0.1.0/.flake8 +16 -0
- open_data_products-0.1.0/.gitignore +7 -0
- open_data_products-0.1.0/.mcp.json +8 -0
- open_data_products-0.1.0/AGENTS.md +102 -0
- open_data_products-0.1.0/BUILD.md +207 -0
- open_data_products-0.1.0/CONTRIBUTING.md +461 -0
- open_data_products-0.1.0/LICENSE +203 -0
- open_data_products-0.1.0/MANIFEST.in +18 -0
- open_data_products-0.1.0/PKG-INFO +421 -0
- open_data_products-0.1.0/README.md +372 -0
- open_data_products-0.1.0/docs/API.md +1247 -0
- open_data_products-0.1.0/docs/agent-surface.md +98 -0
- open_data_products-0.1.0/docs/commands.md +238 -0
- open_data_products-0.1.0/docs/data-contracts.md +65 -0
- open_data_products-0.1.0/docs/functional-test-report.md +86 -0
- open_data_products-0.1.0/docs/generation.md +298 -0
- open_data_products-0.1.0/docs/online-llm-generation-story.md +159 -0
- open_data_products-0.1.0/docs/tooling-development-model.md +145 -0
- open_data_products-0.1.0/examples/advanced_features.py +524 -0
- open_data_products-0.1.0/examples/apps/README.md +41 -0
- open_data_products-0.1.0/examples/apps/document_inspector/cli.py +117 -0
- open_data_products-0.1.0/examples/apps/pricing_402_builder/cli.py +101 -0
- open_data_products-0.1.0/examples/apps/pricing_402_builder/priced_product.yaml +18 -0
- open_data_products-0.1.0/examples/apps/vocabulary_finder/cli.py +103 -0
- open_data_products-0.1.0/examples/basic_usage.py +305 -0
- open_data_products-0.1.0/examples/comprehensive_example.py +177 -0
- open_data_products-0.1.0/examples/contract.yaml +23 -0
- open_data_products-0.1.0/examples/demo_product.json +56 -0
- open_data_products-0.1.0/examples/demo_product.yaml +51 -0
- open_data_products-0.1.0/examples/graph.graphml +15 -0
- open_data_products-0.1.0/examples/guides/01-validate-product.md +55 -0
- open_data_products-0.1.0/examples/guides/02-explain-and-summarize.md +57 -0
- open_data_products-0.1.0/examples/guides/03-use-vocabulary-helpers.md +52 -0
- open_data_products-0.1.0/examples/guides/04-convert-graph-to-odpg.md +62 -0
- open_data_products-0.1.0/examples/guides/05-llm-generate-one-signal.md +61 -0
- open_data_products-0.1.0/examples/guides/06-llm-use-online-provider.md +82 -0
- open_data_products-0.1.0/examples/guides/07-llm-generate-fragment-set.md +79 -0
- open_data_products-0.1.0/examples/guides/08-llm-full-cycle-catalog-and-graph.md +131 -0
- open_data_products-0.1.0/examples/guides/README.md +27 -0
- open_data_products-0.1.0/examples/odpc_catalog.html +142 -0
- open_data_products-0.1.0/examples/odpc_catalog.yaml +34 -0
- open_data_products-0.1.0/examples/odpc_catalog_fragments/catalog_metadata.yaml +6 -0
- open_data_products-0.1.0/examples/odpc_catalog_fragments/customer_product.yaml +11 -0
- open_data_products-0.1.0/examples/odpc_catalog_fragments/customer_retention_use_case.yaml +8 -0
- open_data_products-0.1.0/examples/odps_v41_example.py +280 -0
- open_data_products-0.1.0/examples/product.yaml +146 -0
- open_data_products-0.1.0/images/agent.png +0 -0
- open_data_products-0.1.0/images/feedback.png +0 -0
- open_data_products-0.1.0/images/glance.png +0 -0
- open_data_products-0.1.0/images/llms.png +0 -0
- open_data_products-0.1.0/llms.txt +250 -0
- open_data_products-0.1.0/open_data_products/__init__.py +162 -0
- open_data_products-0.1.0/open_data_products/_io.py +44 -0
- open_data_products-0.1.0/open_data_products/_search.py +55 -0
- open_data_products-0.1.0/open_data_products/agent.py +381 -0
- open_data_products-0.1.0/open_data_products/cli.py +1178 -0
- open_data_products-0.1.0/open_data_products/contracts/__init__.py +60 -0
- open_data_products-0.1.0/open_data_products/contracts/alignment.py +373 -0
- open_data_products-0.1.0/open_data_products/contracts/datacontract_cli_adapter.py +423 -0
- open_data_products-0.1.0/open_data_products/contracts/errors.py +11 -0
- open_data_products-0.1.0/open_data_products/contracts/loader.py +226 -0
- open_data_products-0.1.0/open_data_products/contracts/models.py +244 -0
- open_data_products-0.1.0/open_data_products/contracts/product.py +267 -0
- open_data_products-0.1.0/open_data_products/generation/__init__.py +1047 -0
- open_data_products-0.1.0/open_data_products/generation/data/__init__.py +1 -0
- open_data_products-0.1.0/open_data_products/generation/data/prompts/__init__.py +1 -0
- open_data_products-0.1.0/open_data_products/generation/data/prompts/odpc_objective_fragment.md +59 -0
- open_data_products-0.1.0/open_data_products/generation/data/prompts/odpc_signal_fragment.md +85 -0
- open_data_products-0.1.0/open_data_products/generation/data/prompts/odpc_use_case_fragment.md +60 -0
- open_data_products-0.1.0/open_data_products/generation/data/prompts/odpg_graph_yaml.md +66 -0
- open_data_products-0.1.0/open_data_products/generation/data/prompts/odps_data_product_fragment.md +65 -0
- open_data_products-0.1.0/open_data_products/generation/data/prompts/system.md +23 -0
- open_data_products-0.1.0/open_data_products/generation/fragments/__init__.py +1 -0
- open_data_products-0.1.0/open_data_products/generation/fragments/business_objective_reduce-departure-delay-minutes.yaml +25 -0
- open_data_products-0.1.0/open_data_products/generation/fragments/graph_explorer.html +1920 -0
- open_data_products-0.1.0/open_data_products/generation/fragments/odpg_graph.yaml +91 -0
- open_data_products-0.1.0/open_data_products/generation/fragments/product_reference_airport-operations-performance.yaml +21 -0
- open_data_products-0.1.0/open_data_products/generation/fragments/product_reference_flight-connection-reliability.yaml +21 -0
- open_data_products-0.1.0/open_data_products/generation/fragments/product_reference_passenger-flow-queue.yaml +21 -0
- open_data_products-0.1.0/open_data_products/generation/fragments/signal_baggage-belt-congestion-signal.yaml +28 -0
- open_data_products-0.1.0/open_data_products/generation/fragments/signal_inbound-connection-risk-signal.yaml +31 -0
- open_data_products-0.1.0/open_data_products/generation/fragments/signal_security-queue-surge-signal.yaml +30 -0
- open_data_products-0.1.0/open_data_products/generation/fragments/signal_turnaround-delay-spike-signal.yaml +30 -0
- open_data_products-0.1.0/open_data_products/generation/fragments/use_case_flight-delay-risk-monitoring.yaml +26 -0
- open_data_products-0.1.0/open_data_products/generation/fragments/use_case_passenger-connection-protection.yaml +27 -0
- open_data_products-0.1.0/open_data_products/generation/generation.config.yaml +79 -0
- open_data_products-0.1.0/open_data_products/generation/source_docs/README.md +60 -0
- open_data_products-0.1.0/open_data_products/generation/source_docs/__init__.py +1 -0
- open_data_products-0.1.0/open_data_products/generation/source_docs/airport-business-objective.txt +20 -0
- open_data_products-0.1.0/open_data_products/generation/source_docs/airport-operations-brief.md +26 -0
- open_data_products-0.1.0/open_data_products/generation/source_docs/baggage-belt-congestion-signal.txt +20 -0
- open_data_products-0.1.0/open_data_products/generation/source_docs/connection-reliability-brief.md +26 -0
- open_data_products-0.1.0/open_data_products/generation/source_docs/flight-delay-use-case.md +22 -0
- open_data_products-0.1.0/open_data_products/generation/source_docs/inbound-connection-risk-signal.txt +20 -0
- open_data_products-0.1.0/open_data_products/generation/source_docs/passenger-connection-use-case.md +27 -0
- open_data_products-0.1.0/open_data_products/generation/source_docs/passenger-flow-brief.md +24 -0
- open_data_products-0.1.0/open_data_products/generation/source_docs/security-queue-surge-signal.txt +20 -0
- open_data_products-0.1.0/open_data_products/generation/source_docs/turnaround-delay-signal.txt +20 -0
- open_data_products-0.1.0/open_data_products/mcp/__init__.py +12 -0
- open_data_products-0.1.0/open_data_products/mcp/manifest.py +44 -0
- open_data_products-0.1.0/open_data_products/mcp/server.py +114 -0
- open_data_products-0.1.0/open_data_products/mcp/tools.py +598 -0
- open_data_products-0.1.0/open_data_products/odpc/__init__.py +48 -0
- open_data_products-0.1.0/open_data_products/odpc/catalog.py +692 -0
- open_data_products-0.1.0/open_data_products/odpc/cli.py +143 -0
- open_data_products-0.1.0/open_data_products/odpc/data/__init__.py +1 -0
- open_data_products-0.1.0/open_data_products/odpc/data/catalog/__init__.py +1 -0
- open_data_products-0.1.0/open_data_products/odpc/data/catalog/objects.jsonl +6 -0
- open_data_products-0.1.0/open_data_products/odpc/data/schema/__init__.py +1 -0
- open_data_products-0.1.0/open_data_products/odpc/data/schema/odpc.json +810 -0
- open_data_products-0.1.0/open_data_products/odpc/data/schema/odpc.yaml +590 -0
- open_data_products-0.1.0/open_data_products/odpc/data/templates/__init__.py +1 -0
- open_data_products-0.1.0/open_data_products/odpc/data/templates/catalog.html +128 -0
- open_data_products-0.1.0/open_data_products/odpg/__init__.py +54 -0
- open_data_products-0.1.0/open_data_products/odpg/_explorer_template.py +1634 -0
- open_data_products-0.1.0/open_data_products/odpg/cli.py +309 -0
- open_data_products-0.1.0/open_data_products/odpg/convert.py +533 -0
- open_data_products-0.1.0/open_data_products/odpg/data/__init__.py +0 -0
- open_data_products-0.1.0/open_data_products/odpg/data/graph/__init__.py +0 -0
- open_data_products-0.1.0/open_data_products/odpg/data/graph/graph.yaml +112 -0
- open_data_products-0.1.0/open_data_products/odpg/data/graph/objects.jsonl +63 -0
- open_data_products-0.1.0/open_data_products/odpg/data/schema/__init__.py +0 -0
- open_data_products-0.1.0/open_data_products/odpg/data/schema/odpg.json +276 -0
- open_data_products-0.1.0/open_data_products/odpg/data/schema/odpg.yaml +219 -0
- open_data_products-0.1.0/open_data_products/odpg/graph.py +772 -0
- open_data_products-0.1.0/open_data_products/odps/__init__.py +92 -0
- open_data_products-0.1.0/open_data_products/odps/_document.py +56 -0
- open_data_products-0.1.0/open_data_products/odps/_iso_codes.py +72 -0
- open_data_products-0.1.0/open_data_products/odps/_state.py +63 -0
- open_data_products-0.1.0/open_data_products/odps/_validators.py +338 -0
- open_data_products-0.1.0/open_data_products/odps/codecs.py +614 -0
- open_data_products-0.1.0/open_data_products/odps/core.py +611 -0
- open_data_products-0.1.0/open_data_products/odps/data/__init__.py +1 -0
- open_data_products-0.1.0/open_data_products/odps/data/schema/__init__.py +1 -0
- open_data_products-0.1.0/open_data_products/odps/data/schema/odps.json +1207 -0
- open_data_products-0.1.0/open_data_products/odps/enums.py +308 -0
- open_data_products-0.1.0/open_data_products/odps/exceptions.py +84 -0
- open_data_products-0.1.0/open_data_products/odps/models.py +433 -0
- open_data_products-0.1.0/open_data_products/odps/protocols.py +313 -0
- open_data_products-0.1.0/open_data_products/odps/validation.py +573 -0
- open_data_products-0.1.0/open_data_products/odps/validators.py +8 -0
- open_data_products-0.1.0/open_data_products/odpv/__init__.py +44 -0
- open_data_products-0.1.0/open_data_products/odpv/cli.py +129 -0
- open_data_products-0.1.0/open_data_products/odpv/data/__init__.py +1 -0
- open_data_products-0.1.0/open_data_products/odpv/data/vocab/__init__.py +1 -0
- open_data_products-0.1.0/open_data_products/odpv/data/vocab/core.yaml +363 -0
- open_data_products-0.1.0/open_data_products/odpv/data/vocab/governance.yaml +432 -0
- open_data_products-0.1.0/open_data_products/odpv/data/vocab/odpv.json +2372 -0
- open_data_products-0.1.0/open_data_products/odpv/data/vocab/odpv.yaml +1784 -0
- open_data_products-0.1.0/open_data_products/odpv/data/vocab/relationships.yaml +550 -0
- open_data_products-0.1.0/open_data_products/odpv/data/vocab/terms.jsonl +59 -0
- open_data_products-0.1.0/open_data_products/odpv/data/vocab/value.yaml +423 -0
- open_data_products-0.1.0/open_data_products/odpv/vocabulary.py +559 -0
- open_data_products-0.1.0/open_data_products/pricing.py +53 -0
- open_data_products-0.1.0/open_data_products/resources.py +154 -0
- open_data_products-0.1.0/open_data_products/results.py +55 -0
- open_data_products-0.1.0/open_data_products/summary.py +81 -0
- open_data_products-0.1.0/open_data_products.egg-info/PKG-INFO +421 -0
- open_data_products-0.1.0/open_data_products.egg-info/SOURCES.txt +167 -0
- open_data_products-0.1.0/open_data_products.egg-info/dependency_links.txt +1 -0
- open_data_products-0.1.0/open_data_products.egg-info/entry_points.txt +3 -0
- open_data_products-0.1.0/open_data_products.egg-info/requires.txt +24 -0
- open_data_products-0.1.0/open_data_products.egg-info/top_level.txt +1 -0
- open_data_products-0.1.0/pyproject.toml +206 -0
- open_data_products-0.1.0/requirements.txt +2 -0
- open_data_products-0.1.0/setup.cfg +4 -0
- open_data_products-0.1.0/skills/odp-author/SKILL.md +60 -0
- open_data_products-0.1.0/skills/odp-explore-graph/SKILL.md +57 -0
- open_data_products-0.1.0/skills/odp-validate/SKILL.md +52 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
[flake8]
|
|
2
|
+
max-line-length = 88
|
|
3
|
+
extend-ignore =
|
|
4
|
+
E203,
|
|
5
|
+
E501,
|
|
6
|
+
W503
|
|
7
|
+
exclude =
|
|
8
|
+
.git,
|
|
9
|
+
.mypy_cache,
|
|
10
|
+
.pytest_cache,
|
|
11
|
+
__pycache__,
|
|
12
|
+
build,
|
|
13
|
+
dist,
|
|
14
|
+
open_data_products.egg-info
|
|
15
|
+
per-file-ignores =
|
|
16
|
+
open_data_products/odps/__init__.py:F401,F403,E402
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Instruction file for AI coding agents (Claude Code, Codex, Cursor, Gemini)
|
|
4
|
+
working in this repository. Authoritative project conventions; precedence over
|
|
5
|
+
generic defaults.
|
|
6
|
+
|
|
7
|
+
## Project
|
|
8
|
+
|
|
9
|
+
Python SDK + MCP surface for the OpenDataProducts.org standards family
|
|
10
|
+
(ODPS, ODPC, ODPG, ODPV). Single package: `open_data_products`.
|
|
11
|
+
|
|
12
|
+
## Stack
|
|
13
|
+
|
|
14
|
+
- Python ≥ 3.8 (tested through 3.12; CI runs on 3.14)
|
|
15
|
+
- Runtime deps: `PyYAML`, `certifi`, `jsonschema`, `pycountry`, `phonenumbers`
|
|
16
|
+
- Dev deps: `pytest`, `pytest-cov`, `black`, `flake8`, `mypy`, `build`, `twine`
|
|
17
|
+
- No web framework, no DB, no async runtime.
|
|
18
|
+
|
|
19
|
+
## Style
|
|
20
|
+
|
|
21
|
+
- 4-space indent. Black with `line-length = 88`. No `any` in type hints.
|
|
22
|
+
- Public API surface lives in `open_data_products/__init__.py` — list new
|
|
23
|
+
exports there explicitly; do not rely on barrel re-exports.
|
|
24
|
+
- Per-spec helpers live under `open_data_products/<spec>/`. Cross-spec
|
|
25
|
+
facades live at the package root (`agent.py`, `cli.py`, `summary.py`,
|
|
26
|
+
`pricing.py`, `mcp/`).
|
|
27
|
+
- Internal-only modules use a leading `_` prefix; do not export them.
|
|
28
|
+
- Docstrings: one-line summary, optional short body. No paragraph essays.
|
|
29
|
+
|
|
30
|
+
## Structure
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
open_data_products/
|
|
34
|
+
__init__.py # public API surface
|
|
35
|
+
agent.py # cross-spec load/detect/validate/explain/refs
|
|
36
|
+
cli.py # `open-data-products` console script
|
|
37
|
+
summary.py # load_summary — artifact references (no body)
|
|
38
|
+
pricing.py # ODPS PricingPlans → HTTP 402 envelope
|
|
39
|
+
resources.py # bundled resource registry
|
|
40
|
+
results.py # ValidationResult, Reference, Resource dataclasses
|
|
41
|
+
mcp/
|
|
42
|
+
tools.py # MCP tool registry (data + handlers)
|
|
43
|
+
manifest.py # ARWS agent manifest
|
|
44
|
+
server.py # stdio JSON-RPC 2.0 MCP server
|
|
45
|
+
odps/ # spec-specific package
|
|
46
|
+
odpc/ odpg/ odpv/
|
|
47
|
+
skills/ # SKILL.md bundles for agent hosts
|
|
48
|
+
tests/
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
New code goes in the smallest existing module that fits its spec namespace.
|
|
52
|
+
Do not introduce parallel `validation.py` / `validators.py` style splits;
|
|
53
|
+
that confusion already exists and should be merged, not extended.
|
|
54
|
+
|
|
55
|
+
## Testing
|
|
56
|
+
|
|
57
|
+
- `pytest -q` from repo root. Target: 100% green.
|
|
58
|
+
- New behaviour requires a test in `tests/test_<area>.py`.
|
|
59
|
+
- Conformance to agenticpatterns.veso.ai prescriptions is enforced by
|
|
60
|
+
`tests/test_agentic_patterns.py`. Treat that file as the spec — when
|
|
61
|
+
changing the agent surface, update the test first, watch it fail, then
|
|
62
|
+
implement.
|
|
63
|
+
- Use `tmp_path` fixtures, not real filesystem state.
|
|
64
|
+
|
|
65
|
+
## Git
|
|
66
|
+
|
|
67
|
+
- Branch: `feat/<short-description>`, `fix/<short-description>`, etc.
|
|
68
|
+
- Commit messages: imperative, one logical change per commit.
|
|
69
|
+
- One PR per concern. Don't bundle a refactor with a feature.
|
|
70
|
+
- Never `--amend` after pushing. Never `git push --force` to `main`.
|
|
71
|
+
|
|
72
|
+
## Security
|
|
73
|
+
|
|
74
|
+
- No hardcoded secrets in source or fixtures. The SDK has no credential
|
|
75
|
+
surface today; if you add one, read from env vars and document it here.
|
|
76
|
+
- The MCP server is `safe`-class only today (read-only). When you add a
|
|
77
|
+
`state-changing` or `destructive` tool, set the `class` field in
|
|
78
|
+
`mcp/tools.py` accordingly and update `tests/test_agentic_patterns.py`.
|
|
79
|
+
- Bundled JSON Schemas are loaded with `jsonschema`'s default checker.
|
|
80
|
+
Do not load arbitrary remote schemas at validate time.
|
|
81
|
+
|
|
82
|
+
## Pre-Commit Checklist
|
|
83
|
+
|
|
84
|
+
Before marking work complete, run all four:
|
|
85
|
+
|
|
86
|
+
1. `pytest -q` — all tests pass
|
|
87
|
+
2. `python -c "import open_data_products"` — package imports cleanly
|
|
88
|
+
3. `python -m open_data_products.cli manifest --json | python -m json.tool`
|
|
89
|
+
— manifest renders and parses
|
|
90
|
+
4. No new files in `docs/superpowers/` (that path is reserved for legacy
|
|
91
|
+
AI-planning artifacts already deleted; do not recreate)
|
|
92
|
+
|
|
93
|
+
## Anti-patterns to avoid
|
|
94
|
+
|
|
95
|
+
- Returning full document bodies from MCP handlers — use `load_summary`
|
|
96
|
+
for references; only load full docs when validation/explanation needs them
|
|
97
|
+
- Adding console_script entry points beyond `open-data-products` — the
|
|
98
|
+
unified subcommand CLI is the contract
|
|
99
|
+
- Importing from `open_data_products.odps.codecs` in user-facing code —
|
|
100
|
+
that module is internal glue between models and YAML/JSON
|
|
101
|
+
- Storing absolute filesystem paths in tool responses — return logical IDs
|
|
102
|
+
and let the resource registry resolve them
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# Building and Distributing Open Data Products Python SDK
|
|
2
|
+
|
|
3
|
+
This guide explains how to package the Open Data Products Python SDK as a wheel file for distribution.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install build tools
|
|
9
|
+
pip install build
|
|
10
|
+
|
|
11
|
+
# Build the package with minimal output
|
|
12
|
+
python -m build --quiet
|
|
13
|
+
|
|
14
|
+
# Install locally for testing
|
|
15
|
+
pip install dist/open_data_products-0.2.0-py3-none-any.whl
|
|
16
|
+
|
|
17
|
+
# Test functionality
|
|
18
|
+
python -c "import open_data_products; print(open_data_products.__version__)"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Prerequisites
|
|
22
|
+
|
|
23
|
+
Install build tools:
|
|
24
|
+
```bash
|
|
25
|
+
pip install build twine
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Method 1: Using `build` (Recommended - PEP 517 compliant)
|
|
29
|
+
|
|
30
|
+
The modern way using `pyproject.toml`:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Install build dependencies
|
|
34
|
+
pip install build
|
|
35
|
+
|
|
36
|
+
# Build the package with minimal output (creates both wheel and source distribution)
|
|
37
|
+
python -m build --quiet
|
|
38
|
+
|
|
39
|
+
# This creates files in dist/:
|
|
40
|
+
# - open_data_products-0.2.0-py3-none-any.whl (wheel file)
|
|
41
|
+
# - open_data_products-0.2.0.tar.gz (source distribution)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Method 2: Build with specific options
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Build with clean environment
|
|
48
|
+
python -m build --wheel --outdir dist/
|
|
49
|
+
|
|
50
|
+
# Build source distribution only
|
|
51
|
+
python -m build --sdist
|
|
52
|
+
|
|
53
|
+
# Build with verbose output
|
|
54
|
+
python -m build --wheel --verbose
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
## Installing the Built Wheel
|
|
59
|
+
|
|
60
|
+
After building, install the wheel locally for testing:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Install the built wheel
|
|
64
|
+
pip install dist/open_data_products-0.2.0-py3-none-any.whl
|
|
65
|
+
|
|
66
|
+
# Or install in development mode with extras
|
|
67
|
+
pip install -e ".[dev]"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Verifying the Package
|
|
71
|
+
|
|
72
|
+
Test the installed package:
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
import open_data_products
|
|
76
|
+
print(open_data_products.__version__) # Should print 0.2.0
|
|
77
|
+
|
|
78
|
+
from open_data_products.odps import OpenDataProduct, ODPSValidator
|
|
79
|
+
from open_data_products.odps.models import ProductDetails
|
|
80
|
+
|
|
81
|
+
# Test basic functionality
|
|
82
|
+
product = ProductDetails(
|
|
83
|
+
name="Test",
|
|
84
|
+
product_id="test-001",
|
|
85
|
+
visibility="public",
|
|
86
|
+
status="production",
|
|
87
|
+
type="dataset"
|
|
88
|
+
)
|
|
89
|
+
odp = OpenDataProduct(product)
|
|
90
|
+
odp.validate()
|
|
91
|
+
print("✓ Package working correctly")
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Publishing to PyPI
|
|
95
|
+
|
|
96
|
+
### Test PyPI (Recommended for testing)
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Upload to Test PyPI first
|
|
100
|
+
python -m twine upload --repository testpypi dist/*
|
|
101
|
+
|
|
102
|
+
# Install from Test PyPI to verify
|
|
103
|
+
pip install --index-url https://test.pypi.org/simple/ odps-python
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Production PyPI
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Upload to production PyPI
|
|
110
|
+
python -m twine upload dist/*
|
|
111
|
+
|
|
112
|
+
# Configure credentials first:
|
|
113
|
+
# Create ~/.pypirc with your API tokens
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Package Structure
|
|
117
|
+
|
|
118
|
+
The built wheel contains:
|
|
119
|
+
```
|
|
120
|
+
odps_python-0.2.0-py3-none-any.whl
|
|
121
|
+
├── odps/
|
|
122
|
+
│ ├── __init__.py # Package entry point with version
|
|
123
|
+
│ ├── core.py # Main OpenDataProduct class
|
|
124
|
+
│ ├── models.py # Data models for ODPS components
|
|
125
|
+
│ └── validators.py # International standards validation
|
|
126
|
+
├── odps_python-0.2.0.dist-info/
|
|
127
|
+
│ ├── METADATA # Package metadata
|
|
128
|
+
│ ├── WHEEL # Wheel metadata
|
|
129
|
+
│ ├── RECORD # File checksums
|
|
130
|
+
│ └── top_level.txt # Top-level packages
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Build Configuration
|
|
134
|
+
|
|
135
|
+
### pyproject.toml (Modern)
|
|
136
|
+
- Defines build system requirements
|
|
137
|
+
- Specifies metadata and dependencies
|
|
138
|
+
- Configures development tools (black, mypy)
|
|
139
|
+
- PEP 517/518 compliant
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
## Troubleshooting
|
|
143
|
+
|
|
144
|
+
### Common Issues
|
|
145
|
+
|
|
146
|
+
1. **Import errors during build**:
|
|
147
|
+
```bash
|
|
148
|
+
# Ensure all dependencies are installed
|
|
149
|
+
pip install -r requirements.txt
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
2. **Version conflicts**:
|
|
153
|
+
```bash
|
|
154
|
+
# Clean previous builds
|
|
155
|
+
rm -rf build/ dist/ *.egg-info/
|
|
156
|
+
python -m build --quiet
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
3. **Missing files in wheel**:
|
|
160
|
+
```bash
|
|
161
|
+
# Check MANIFEST.in or pyproject.toml package discovery
|
|
162
|
+
python -m build --verbose
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
4. **Upload failures**:
|
|
166
|
+
```bash
|
|
167
|
+
# Check credentials and package name availability
|
|
168
|
+
python -m twine check dist/*
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Distribution Checklist
|
|
172
|
+
|
|
173
|
+
- [ ] Version number updated in `__init__.py`
|
|
174
|
+
- [ ] CHANGELOG.md updated with release notes
|
|
175
|
+
- [ ] README.md reflects current features
|
|
176
|
+
- [ ] All tests passing
|
|
177
|
+
- [ ] Dependencies properly specified
|
|
178
|
+
- [ ] Built wheel installs and imports correctly
|
|
179
|
+
- [ ] Uploaded to Test PyPI successfully
|
|
180
|
+
- [ ] Documentation is current
|
|
181
|
+
|
|
182
|
+
## Automated Building
|
|
183
|
+
|
|
184
|
+
For CI/CD, add to your workflow:
|
|
185
|
+
|
|
186
|
+
```yaml
|
|
187
|
+
# .github/workflows/build.yml
|
|
188
|
+
name: Build and Test
|
|
189
|
+
on: [push, pull_request]
|
|
190
|
+
jobs:
|
|
191
|
+
build:
|
|
192
|
+
runs-on: ubuntu-latest
|
|
193
|
+
steps:
|
|
194
|
+
- uses: actions/checkout@v3
|
|
195
|
+
- name: Set up Python
|
|
196
|
+
uses: actions/setup-python@v4
|
|
197
|
+
with:
|
|
198
|
+
python-version: 3.9
|
|
199
|
+
- name: Install dependencies
|
|
200
|
+
run: |
|
|
201
|
+
pip install build twine
|
|
202
|
+
pip install -e ".[dev]"
|
|
203
|
+
- name: Build package
|
|
204
|
+
run: python -m build --quiet
|
|
205
|
+
- name: Check package
|
|
206
|
+
run: python -m twine check dist/*
|
|
207
|
+
```
|