strapi-kit 0.0.1__tar.gz → 0.0.3__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 (102) hide show
  1. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/.github/workflows/ci.yml +10 -3
  2. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/.github/workflows/dev-release.yml +1 -1
  3. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/.github/workflows/release.yml +1 -1
  4. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/.gitignore +5 -0
  5. strapi_kit-0.0.3/AGENTS.md +54 -0
  6. strapi_kit-0.0.3/CHANGELOG.md +69 -0
  7. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/CLAUDE.md +8 -1
  8. strapi_kit-0.0.3/LLM.md +502 -0
  9. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/PKG-INFO +214 -21
  10. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/README.md +212 -20
  11. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/docs/changelog.md +20 -1
  12. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/examples/basic_crud.py +4 -1
  13. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/examples/full_migration_v5.py +90 -33
  14. strapi_kit-0.0.3/examples/simple_migration.py +223 -0
  15. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/pyproject.toml +1 -0
  16. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/_version.py +2 -2
  17. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/client/async_client.py +87 -1
  18. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/client/base.py +91 -2
  19. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/client/sync_client.py +87 -1
  20. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/config_provider.py +1 -16
  21. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/exceptions/__init__.py +2 -0
  22. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/exceptions/errors.py +13 -0
  23. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/export/exporter.py +6 -5
  24. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/__init__.py +8 -0
  25. strapi_kit-0.0.3/src/strapi_kit/models/content_type.py +148 -0
  26. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/export_format.py +5 -3
  27. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/request/query.py +9 -6
  28. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/operations/media.py +13 -6
  29. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/operations/streaming.py +5 -4
  30. strapi_kit-0.0.3/src/strapi_kit/utils/__init__.py +34 -0
  31. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/utils/rate_limiter.py +4 -2
  32. strapi_kit-0.0.3/src/strapi_kit/utils/seo.py +294 -0
  33. strapi_kit-0.0.3/src/strapi_kit/utils/uid.py +206 -0
  34. strapi_kit-0.0.1/.github/workflows/publish-testpypi.yml +0 -208
  35. strapi_kit-0.0.1/examples/simple_migration.py +0 -90
  36. strapi_kit-0.0.1/src/strapi_kit/utils/__init__.py +0 -15
  37. strapi_kit-0.0.1/src/strapi_kit/utils/uid.py +0 -88
  38. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/.coderabbit.yaml +0 -0
  39. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/.env.example +0 -0
  40. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/.github/dependabot.yml +0 -0
  41. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/.github/pull_request_template.md +0 -0
  42. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/.github/workflows/document.yml +0 -0
  43. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/.github/workflows/guard-main-origin.yml +0 -0
  44. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/.pre-commit-config.yaml +0 -0
  45. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/.secrets.baseline +0 -0
  46. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/LICENSE +0 -0
  47. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/Makefile +0 -0
  48. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/codecov.yml +0 -0
  49. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/docs/configuration.md +0 -0
  50. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/docs/development/architecture.md +0 -0
  51. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/docs/development/contributing.md +0 -0
  52. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/docs/development/release-process.md +0 -0
  53. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/docs/development/testing.md +0 -0
  54. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/docs/export-import.md +0 -0
  55. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/docs/index.md +0 -0
  56. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/docs/installation.md +0 -0
  57. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/docs/media.md +0 -0
  58. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/docs/models.md +0 -0
  59. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/docs/quickstart.md +0 -0
  60. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/docs/stylesheets/extra.css +0 -0
  61. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/examples/MIGRATION_GUIDE.md +0 -0
  62. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/examples/async_operations.py +0 -0
  63. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/examples/config_di_demo.py +0 -0
  64. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/examples/export_import_with_media.py +0 -0
  65. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/examples/export_import_with_schemas.py +0 -0
  66. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/examples/verify_installation.py +0 -0
  67. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/mkdocs.yml +0 -0
  68. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/__init__.py +1 -1
  69. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/__version__.py +0 -0
  70. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/auth/__init__.py +0 -0
  71. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/auth/api_token.py +0 -0
  72. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/cache/__init__.py +0 -0
  73. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/cache/schema_cache.py +0 -0
  74. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/client/__init__.py +0 -0
  75. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/export/__init__.py +0 -0
  76. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/export/importer.py +0 -0
  77. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/export/media_handler.py +0 -0
  78. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/export/relation_resolver.py +0 -0
  79. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/bulk.py +0 -0
  80. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/config.py +0 -0
  81. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/enums.py +0 -0
  82. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/import_options.py +0 -0
  83. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/request/__init__.py +0 -0
  84. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/request/fields.py +0 -0
  85. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/request/filters.py +0 -0
  86. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/request/pagination.py +0 -0
  87. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/request/populate.py +0 -0
  88. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/request/sort.py +0 -0
  89. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/response/__init__.py +0 -0
  90. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/response/base.py +0 -0
  91. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/response/component.py +0 -0
  92. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/response/media.py +0 -0
  93. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/response/meta.py +0 -0
  94. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/response/normalized.py +0 -0
  95. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/response/relation.py +0 -0
  96. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/response/v4.py +0 -0
  97. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/response/v5.py +0 -0
  98. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/models/schema.py +0 -0
  99. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/operations/__init__.py +0 -0
  100. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/parsers/__init__.py +0 -0
  101. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/parsers/version_detecting.py +0 -0
  102. {strapi_kit-0.0.1 → strapi_kit-0.0.3}/src/strapi_kit/protocols.py +0 -0
@@ -80,17 +80,24 @@ jobs:
80
80
  # Install project with dev dependencies
81
81
  uv pip install --system -e ".[dev]"
82
82
 
83
- # Run tests with coverage
84
- pytest --cov=strapi_kit --cov-report=xml --cov-report=term -v
83
+ # Run tests with coverage and JUnit XML for test analytics
84
+ pytest --cov=strapi_kit --cov-report=xml --cov-report=term --junitxml=junit.xml -o junit_family=legacy -v
85
85
 
86
- - name: 📈 Coverage upload
86
+ - name: 📈 Upload coverage to Codecov
87
87
  uses: codecov/codecov-action@v5
88
88
  with:
89
89
  token: ${{ secrets.CODECOV_TOKEN }}
90
+ slug: MehdiZare/strapi-kit
90
91
  files: coverage.xml
91
92
  flags: unittests
92
93
  fail_ci_if_error: false
93
94
 
95
+ - name: 📊 Upload test results to Codecov
96
+ if: ${{ !cancelled() }}
97
+ uses: codecov/test-results-action@v1
98
+ with:
99
+ token: ${{ secrets.CODECOV_TOKEN }}
100
+
94
101
  test-matrix-expected:
95
102
  name: Test-MatrixExpected
96
103
  runs-on: ubuntu-latest
@@ -125,7 +125,7 @@ jobs:
125
125
  fi
126
126
 
127
127
  - name: 🧪 Upload to Test PyPI
128
- uses: pypa/gh-action-pypi-publish@v1.13.0
128
+ uses: pypa/gh-action-pypi-publish@release/v1
129
129
  with:
130
130
  repository-url: https://test.pypi.org/legacy/
131
131
  packages-dir: dist
@@ -165,7 +165,7 @@ jobs:
165
165
  generate_release_notes: true
166
166
 
167
167
  - name: 🚀 Publish to PyPI
168
- uses: pypa/gh-action-pypi-publish@v1.13.0
168
+ uses: pypa/gh-action-pypi-publish@release/v1
169
169
  with:
170
170
  packages-dir: dist/
171
171
  skip-existing: false
@@ -172,3 +172,8 @@ tmp/
172
172
 
173
173
  # Hatch version file (auto-generated during build)
174
174
  src/strapi_kit/_version.py
175
+
176
+ # Node.js (not used in this project)
177
+ node_modules/
178
+ package.json
179
+ package-lock.json
@@ -0,0 +1,54 @@
1
+ # Repository Guidelines
2
+
3
+ ## Project Structure & Module Organization
4
+ - `src/strapi_kit/`: library source (clients, models, query builder, migrations, etc.).
5
+ - `tests/`: automated tests organized by scope: `unit/`, `integration/`, `e2e/`.
6
+ - `docs/`: MkDocs documentation source; `site/` is generated output.
7
+ - `examples/`: runnable usage samples and migration scripts.
8
+
9
+ ## Build, Test, and Development Commands
10
+ ```bash
11
+ # Install (uv preferred)
12
+ uv pip install -e ".[dev]" # or: make install-dev
13
+
14
+ # Quality and tests
15
+ make test # pytest
16
+ make coverage # coverage report (htmlcov/)
17
+ make lint # ruff check
18
+ make format # ruff format
19
+ make type-check # mypy strict
20
+ make pre-commit # format + lint-fix + type-check + test
21
+
22
+ # Docs
23
+ make docs-serve # local docs at http://127.0.0.1:8000
24
+
25
+ # E2E (requires Strapi via Docker)
26
+ make e2e-setup # start Strapi
27
+ make e2e # run e2e tests
28
+ make e2e-teardown # stop Strapi
29
+ ```
30
+
31
+ ## Coding Style & Naming Conventions
32
+ - Python 3.12+, PEP 8, line length 100 (enforced by Ruff).
33
+ - Use `ruff format` for formatting and `ruff check` for linting.
34
+ - `mypy` runs in strict mode on `src/strapi_kit/`; type hints are expected for all functions.
35
+ - Prefer f-strings and Google-style docstrings.
36
+ - Use project exception types (e.g., from `strapi_kit.exceptions`) and chain errors with `raise ... from e`.
37
+
38
+ ## Testing Guidelines
39
+ - Frameworks: `pytest`, `pytest-asyncio` (auto mode), `respx` for HTTP mocking.
40
+ - Naming: `test_*.py`, `Test*` classes, `test_*` functions (per pytest config).
41
+ - Organize by scope: unit tests are fast/isolated; integration tests require a real Strapi instance; e2e tests are Docker-backed.
42
+ - Coverage target: 85%+ overall.
43
+
44
+ ## Commit & Pull Request Guidelines
45
+ - Recent history uses descriptive sentence-style messages (e.g., “Add…”, “Refactor…”), but the contributing guide requests **Conventional Commits**.
46
+ - Use conventional commit format in commits and PR titles, e.g. `feat(client): add retry logic`.
47
+ - PRs should describe what/why, link issues, note breaking changes, and include screenshots for UI changes.
48
+ - Expect automated review by CodeRabbit; ensure `pytest`, `mypy`, and `ruff` pass.
49
+
50
+ ## Security & Configuration
51
+ - Run security checks with `make security` (Bandit). Use `make security-baseline` to refresh `.secrets.baseline` when needed.
52
+
53
+ ## Agent-Specific Instructions
54
+ - If you are an AI assistant, consult `CLAUDE.md` and `LLM.md` for workflow conventions and architecture notes.
@@ -0,0 +1,69 @@
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
+ ## [Unreleased]
9
+
10
+ ### Added
11
+
12
+ - **Content-Type Builder API** ([#15](https://github.com/MehdiZare/strapi-kit/issues/15))
13
+ - `get_content_types(include_plugins=False)` - List all content types from Strapi
14
+ - `get_components()` - List all components
15
+ - `get_content_type_schema(uid)` - Get full schema for a content type
16
+ - New models: `ContentTypeListItem`, `ComponentListItem`, `CTBContentTypeSchema`, `CTBContentTypeInfo`
17
+ - Schema helper methods: `get_field_type()`, `is_relation_field()`, `is_component_field()`, `get_relation_target()`, `get_component_uid()`
18
+ - Full async support for all methods
19
+
20
+ - **UID Conversion Utilities** ([#16](https://github.com/MehdiZare/strapi-kit/issues/16))
21
+ - `api_id_to_singular()` - Convert plural API IDs to singular form (handles irregular plurals like people→person, children→child)
22
+ - `uid_to_admin_url()` - Build Strapi admin panel URLs from content type UIDs
23
+ - `uid_to_api_id` - Alias for `uid_to_endpoint` for clarity
24
+ - Export of existing utilities: `extract_model_name()`, `is_api_content_type()`
25
+
26
+ - **SEO Configuration Detection** ([#17](https://github.com/MehdiZare/strapi-kit/issues/17))
27
+ - `detect_seo_configuration()` - Detect SEO setup in content type schemas
28
+ - `SEOConfiguration` dataclass for structured detection results
29
+ - Support for component-based SEO (shared.seo, meta, metadata)
30
+ - Support for flat SEO fields (metaTitle, meta_description, ogTitle, etc.)
31
+ - Case-insensitive matching for field names and component UIDs
32
+
33
+ ### Changed
34
+
35
+ - Test coverage increased from 85% to 86% (528 passing tests)
36
+ - Added 68 new tests for Content-Type Builder, UID utilities, and SEO detection
37
+
38
+ ## [0.0.2] - 2025-01-XX
39
+
40
+ ### Added
41
+
42
+ - Export/Import functionality with automatic relation resolution
43
+ - Schema caching for efficient content type metadata handling
44
+ - Media file export/download support
45
+ - Full migration examples (simple and production-ready)
46
+
47
+ ### Changed
48
+
49
+ - Improved test coverage to 85%
50
+
51
+ ## [0.0.1] - 2025-01-XX
52
+
53
+ ### Added
54
+
55
+ - Initial release
56
+ - HTTP clients (sync and async)
57
+ - Configuration with Pydantic and environment variable support
58
+ - Authentication (API tokens)
59
+ - Exception hierarchy with semantic error types
60
+ - API version detection (v4/v5)
61
+ - Type-safe query builder with 24 filter operators
62
+ - Response normalization for both Strapi v4 and v5
63
+ - Media upload/download operations
64
+ - Dependency injection support with protocols
65
+ - Full type hints and mypy strict mode compliance
66
+
67
+ [Unreleased]: https://github.com/MehdiZare/strapi-kit/compare/v0.0.2...HEAD
68
+ [0.0.2]: https://github.com/MehdiZare/strapi-kit/compare/v0.0.1...v0.0.2
69
+ [0.0.1]: https://github.com/MehdiZare/strapi-kit/releases/tag/v0.0.1
@@ -284,10 +284,11 @@ assert len(mock_http.requests) == 1
284
284
 
285
285
  ```
286
286
  StrapiError (base)
287
+ ├─ ConfigurationError (invalid config, missing token, bad URL)
287
288
  ├─ AuthenticationError (401)
288
289
  ├─ AuthorizationError (403)
289
290
  ├─ NotFoundError (404)
290
- ├─ ValidationError (400)
291
+ ├─ ValidationError (400, input validation)
291
292
  ├─ ConflictError (409)
292
293
  ├─ ServerError (5xx)
293
294
  ├─ NetworkError (connection issues)
@@ -302,6 +303,12 @@ StrapiError (base)
302
303
 
303
304
  **Usage pattern**: Always catch specific exceptions before generic ones. All exceptions carry optional `details: dict[str, Any]` for context.
304
305
 
306
+ **Non-HTTP exceptions**:
307
+ - `ConfigurationError`: Invalid API token, missing config, bad base URL
308
+ - `ValidationError`: Invalid query parameters (pagination, filters), invalid function arguments
309
+ - `FormatError`: Invalid export data format, path traversal prevention
310
+ - `MediaError`: File not found, upload/download failures, context manager misuse
311
+
305
312
  **HTTP mapping** (client/base.py:_handle_error_response):
306
313
  - 401 → AuthenticationError
307
314
  - 403 → AuthorizationError