strapi-kit 0.0.5__py3-none-any.whl → 0.0.6__py3-none-any.whl

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.
strapi_kit/_version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.0.5'
32
- __version_tuple__ = version_tuple = (0, 0, 5)
31
+ __version__ = version = '0.0.6'
32
+ __version_tuple__ = version_tuple = (0, 0, 6)
33
33
 
34
34
  __commit_id__ = commit_id = None
strapi_kit/client/base.py CHANGED
@@ -465,6 +465,57 @@ class BaseClient:
465
465
  # Media list follows standard collection format
466
466
  return self._parse_collection_response(response_data)
467
467
 
468
+ def _normalize_content_type_item(self, item: dict[str, Any]) -> dict[str, Any]:
469
+ """Normalize content type item - flatten v5 schema to v4 format.
470
+
471
+ Strapi v5 returns content types with a nested 'schema' structure:
472
+ {"uid": "...", "apiID": "...", "schema": {"kind": "...", "info": {...}, ...}}
473
+
474
+ This method flattens it to v4 format:
475
+ {"uid": "...", "kind": "...", "info": {...}, "attributes": {...}}
476
+
477
+ Args:
478
+ item: Raw content type item from API response
479
+
480
+ Returns:
481
+ Normalized content type item in v4-compatible format
482
+ """
483
+ if "schema" in item and isinstance(item["schema"], dict):
484
+ schema = item["schema"]
485
+ return {
486
+ "uid": item.get("uid", ""),
487
+ "kind": schema.get("kind", "collectionType"),
488
+ "info": schema.get("info", {}),
489
+ "attributes": schema.get("attributes", {}),
490
+ "pluginOptions": schema.get("pluginOptions"),
491
+ }
492
+ return item
493
+
494
+ def _normalize_component_item(self, item: dict[str, Any]) -> dict[str, Any]:
495
+ """Normalize component item - flatten v5 schema to v4 format.
496
+
497
+ Strapi v5 returns components with a nested 'schema' structure:
498
+ {"uid": "...", "category": "...", "schema": {"info": {...}, "attributes": {...}}}
499
+
500
+ This method flattens it to v4 format:
501
+ {"uid": "...", "category": "...", "info": {...}, "attributes": {...}}
502
+
503
+ Args:
504
+ item: Raw component item from API response
505
+
506
+ Returns:
507
+ Normalized component item in v4-compatible format
508
+ """
509
+ if "schema" in item and isinstance(item["schema"], dict):
510
+ schema = item["schema"]
511
+ return {
512
+ "uid": item.get("uid", ""),
513
+ "category": item.get("category", schema.get("category", "")),
514
+ "info": schema.get("info", {}),
515
+ "attributes": schema.get("attributes", {}),
516
+ }
517
+ return item
518
+
468
519
  def _parse_content_types_response(
469
520
  self,
470
521
  response_data: dict[str, Any],
@@ -472,6 +523,8 @@ class BaseClient:
472
523
  ) -> list["ContentTypeListItem"]:
473
524
  """Parse content-type-builder content types response.
474
525
 
526
+ Automatically normalizes v5 nested schema format to v4 flat format.
527
+
475
528
  Args:
476
529
  response_data: Raw JSON response from content-type-builder
477
530
  include_plugins: Whether to include plugin content types
@@ -491,7 +544,8 @@ class BaseClient:
491
544
  continue
492
545
 
493
546
  try:
494
- content_type = ContentTypeListItem.model_validate(item)
547
+ normalized_item = self._normalize_content_type_item(item)
548
+ content_type = ContentTypeListItem.model_validate(normalized_item)
495
549
  result.append(content_type)
496
550
  except PydanticValidationError as e:
497
551
  # Skip malformed items
@@ -506,6 +560,8 @@ class BaseClient:
506
560
  ) -> list["ComponentListItem"]:
507
561
  """Parse content-type-builder components response.
508
562
 
563
+ Automatically normalizes v5 nested schema format to v4 flat format.
564
+
509
565
  Args:
510
566
  response_data: Raw JSON response from content-type-builder
511
567
 
@@ -520,7 +576,8 @@ class BaseClient:
520
576
  for item in data:
521
577
  uid = item.get("uid", "")
522
578
  try:
523
- component = ComponentListItem.model_validate(item)
579
+ normalized_item = self._normalize_component_item(item)
580
+ component = ComponentListItem.model_validate(normalized_item)
524
581
  result.append(component)
525
582
  except PydanticValidationError as e:
526
583
  # Skip malformed items
@@ -535,6 +592,8 @@ class BaseClient:
535
592
  ) -> "CTBContentTypeSchema":
536
593
  """Parse content-type-builder single content type schema response.
537
594
 
595
+ Automatically normalizes v5 nested schema format to v4 flat format.
596
+
538
597
  Args:
539
598
  response_data: Raw JSON response from content-type-builder
540
599
 
@@ -548,7 +607,8 @@ class BaseClient:
548
607
 
549
608
  data = response_data.get("data", response_data)
550
609
  try:
551
- return CTBContentTypeSchema.model_validate(data)
610
+ normalized_data = self._normalize_content_type_item(data)
611
+ return CTBContentTypeSchema.model_validate(normalized_data)
552
612
  except PydanticValidationError as e:
553
613
  raise ValidationError(
554
614
  "Invalid content type schema response",
@@ -17,7 +17,10 @@ class RetryConfig(BaseSettings):
17
17
  Controls how the client handles failed requests with exponential backoff.
18
18
  """
19
19
 
20
- model_config = SettingsConfigDict(env_prefix="STRAPI_RETRY_")
20
+ model_config = SettingsConfigDict(
21
+ env_prefix="STRAPI_RETRY_",
22
+ extra="ignore",
23
+ )
21
24
 
22
25
  max_attempts: int = Field(
23
26
  default=3,
@@ -77,6 +80,7 @@ class StrapiConfig(BaseSettings):
77
80
  env_file=".env",
78
81
  env_file_encoding="utf-8",
79
82
  case_sensitive=False,
83
+ extra="ignore",
80
84
  )
81
85
 
82
86
  base_url: str = Field(
@@ -6,7 +6,7 @@ This module defines core enums used throughout the models package:
6
6
  - PublicationState: Draft, published, preview content states
7
7
  """
8
8
 
9
- from enum import Enum
9
+ from enum import StrEnum
10
10
  from typing import Literal
11
11
 
12
12
  # Type aliases for common Strapi types
@@ -14,7 +14,7 @@ StrapiVersion = Literal["v4", "v5", "auto"]
14
14
  LocaleCode = str # ISO 639-1 language codes (e.g., "en", "fr", "de")
15
15
 
16
16
 
17
- class FilterOperator(str, Enum):
17
+ class FilterOperator(StrEnum):
18
18
  """Filter operators supported by Strapi REST API.
19
19
 
20
20
  Strapi supports 24 filter operators for querying content.
@@ -66,7 +66,7 @@ class FilterOperator(str, Enum):
66
66
  NOT = "$not" # Logical NOT
67
67
 
68
68
 
69
- class SortDirection(str, Enum):
69
+ class SortDirection(StrEnum):
70
70
  """Sort direction for query results.
71
71
 
72
72
  Examples:
@@ -80,7 +80,7 @@ class SortDirection(str, Enum):
80
80
  DESC = "desc" # Descending order (Z-A, 9-0, newest-oldest)
81
81
 
82
82
 
83
- class PublicationState(str, Enum):
83
+ class PublicationState(StrEnum):
84
84
  """Content publication state filter.
85
85
 
86
86
  Only applicable to content types with draft & publish enabled.
@@ -4,12 +4,12 @@ Defines how imported data should be processed and validated.
4
4
  """
5
5
 
6
6
  from collections.abc import Callable
7
- from enum import Enum
7
+ from enum import StrEnum
8
8
 
9
9
  from pydantic import BaseModel, Field
10
10
 
11
11
 
12
- class ConflictResolution(str, Enum):
12
+ class ConflictResolution(StrEnum):
13
13
  """Strategy for handling conflicts during import.
14
14
 
15
15
  Attributes:
@@ -1,11 +1,11 @@
1
1
  """Content type schema models."""
2
2
 
3
- from enum import Enum
3
+ from enum import StrEnum
4
4
 
5
5
  from pydantic import BaseModel, Field
6
6
 
7
7
 
8
- class FieldType(str, Enum):
8
+ class FieldType(StrEnum):
9
9
  """Field types in Strapi."""
10
10
 
11
11
  STRING = "string"
@@ -31,7 +31,7 @@ class FieldType(str, Enum):
31
31
  UID = "uid"
32
32
 
33
33
 
34
- class RelationType(str, Enum):
34
+ class RelationType(StrEnum):
35
35
  """Relation types in Strapi."""
36
36
 
37
37
  ONE_TO_ONE = "oneToOne"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: strapi-kit
3
- Version: 0.0.5
3
+ Version: 0.0.6
4
4
  Summary: A modern Python client for Strapi CMS with import/export capabilities
5
5
  Project-URL: Homepage, https://github.com/mehdizare/strapi-kit
6
6
  Project-URL: Documentation, https://mehdizare.github.io/strapi-kit/
@@ -1,6 +1,6 @@
1
1
  strapi_kit/__init__.py,sha256=z4BR2eysdjTvsFaTqyUX0aPnSODMC2MyhdpvtCgWHVY,2177
2
2
  strapi_kit/__version__.py,sha256=oLc_AUMPwiL7J2vgrvXdzVqbSQl2hqkPZ6dNfUx1lTU,478
3
- strapi_kit/_version.py,sha256=YRV1ohn6CdKEhsUOmFFMmr5UTjMv4Ydw3WJGxF2BHBs,704
3
+ strapi_kit/_version.py,sha256=7MyqQ3iPP2mJruPfRYGCNCq1z7_Nk7c-eyYecYITxsY,704
4
4
  strapi_kit/config_provider.py,sha256=Eky8mH6XgvgrwzsQuAc4gPpbPby_miycxqQH175rlU4,11864
5
5
  strapi_kit/protocols.py,sha256=wMeGSFCSxeamv2YDzWWWSVJtiGrm__1Xg00QighEbQ4,10971
6
6
  strapi_kit/auth/__init__.py,sha256=VhjbOiyBVSafz3lf2a43bnbSm0J8PG-lguIKHlRplx8,117
@@ -9,7 +9,7 @@ strapi_kit/cache/__init__.py,sha256=MpqVNsjbE6_QGEwyxZ80h-PFkB8NzDv7xGxJK1g5agQ,
9
9
  strapi_kit/cache/schema_cache.py,sha256=cmZBS2E0m0YyxpqS7_Z9evDqu_JZxQH086Vv7th7140,6552
10
10
  strapi_kit/client/__init__.py,sha256=R9Ux5bCret4mnXItnFh5MxYlMOjoS4bepPX1KpNSs5w,216
11
11
  strapi_kit/client/async_client.py,sha256=GUWFfUABcm6tJgWb9CaoYGhfEu7lmZx_nKUr0v97tJ4,39021
12
- strapi_kit/client/base.py,sha256=wzjDSH1bZ8us7iIuSJbi6C7cyqIKbiOaIBunMAiiIa0,19923
12
+ strapi_kit/client/base.py,sha256=Xn8Xqi5wghHTJc7nVJikcOpGSzK40fz-_P3Ao8lKLFo,22431
13
13
  strapi_kit/client/sync_client.py,sha256=bJGzhdTedIl2nnZqjzASEyejiOHM8-_AlubItp_IqcY,36078
14
14
  strapi_kit/exceptions/__init__.py,sha256=lGjEMAbbKO4MXIodY6jxF5x0WerbSZEnYL_r990tzXM,748
15
15
  strapi_kit/exceptions/errors.py,sha256=Yc051k-3tCmT7ybJjQXs9V_i6bh0pY4xW6zmTT7i4PQ,5328
@@ -20,12 +20,12 @@ strapi_kit/export/media_handler.py,sha256=xmx06M4ehtpNpVDwwuppwGpLwRd9s2M-NNnQ7I
20
20
  strapi_kit/export/relation_resolver.py,sha256=bXsrY80JWdvzmfFZc0UIpluReg9BWWBdr5SXhEqlaCs,5660
21
21
  strapi_kit/models/__init__.py,sha256=zm-V86_4yWVS0LGezajQvK0lALmHiZtX8o0tC0QVBk0,3441
22
22
  strapi_kit/models/bulk.py,sha256=g1swXgk8nWE_C-u6LIwKJzk2E5xmqMxDMQgY6SzxY7Q,2100
23
- strapi_kit/models/config.py,sha256=Nq1pWlDc50wSV3RvQseKG688zlHw8vlNFRZqAPtvj0Q,4543
23
+ strapi_kit/models/config.py,sha256=xuYEH0EgJzUiE8T5Nxuln01FQdNgzHJdsVNuLbYcoIE,4606
24
24
  strapi_kit/models/content_type.py,sha256=AIONiPq6-ZyNdoAygiR1_ynh-s2d5ti2GvtmnaktzMs,4150
25
- strapi_kit/models/enums.py,sha256=sxxlBNwOyxasqI7hwTanrv1kppseIkNUf-3SJF15TH8,2939
25
+ strapi_kit/models/enums.py,sha256=y8cNZ_2fktdrI8ggJkd-DHfuKUepN-ZZC_PE0mgg2nE,2936
26
26
  strapi_kit/models/export_format.py,sha256=x8cH-uktCaUVxOJCVtLdS1gs3NpNqTqExWQa5wWoEqc,5351
27
- strapi_kit/models/import_options.py,sha256=aRjWSI2ZOPl8j0ZiLlR8TfAjLrpzn7HBpK1LQ3Rt1IA,4795
28
- strapi_kit/models/schema.py,sha256=qNU7v_HF0AESDqmmKmMy_ERPOI-zUqFCujlAjTZ1Lo8,2489
27
+ strapi_kit/models/import_options.py,sha256=9WmD5TlhTkYqVf-JLs44IzrsoarKMkrVutFNiOvapXw,4796
28
+ strapi_kit/models/schema.py,sha256=tqpt7j-OuvzbzcN8jmBL5plsHHx9pCCOc2BBb8ebnyc,2488
29
29
  strapi_kit/models/request/__init__.py,sha256=RvuVgPvc2tAx9A_Esh04SZZ5Oi1GFiYpxdg90TLsd6A,54
30
30
  strapi_kit/models/request/fields.py,sha256=VrPyf0Pg_EQ3z2IyzBhaw_4fr7N5VWJRcN2Li7ZyZ2w,1828
31
31
  strapi_kit/models/request/filters.py,sha256=3qMzI8cTMfYCFWRAGMbw6DmEBtD2yUWB4UswABQavR4,19274
@@ -51,7 +51,7 @@ strapi_kit/utils/__init__.py,sha256=FFSuu9W6Yt1r0OEU55bs9zLz2RuAy0wCVPfzN2BRz7E,
51
51
  strapi_kit/utils/rate_limiter.py,sha256=c-oAgCILG-6nrjhxIXEx3sKqRgkxOHcNJE496ix7aVA,6367
52
52
  strapi_kit/utils/seo.py,sha256=p1CR3NGPJfarLosqRa3PAgigS9l9IB_LXUMjaZBXDeM,9317
53
53
  strapi_kit/utils/uid.py,sha256=IcGlFKxtyIIWm9TKVMDX4WseSCMS5FLLDNJItSZgIoA,6797
54
- strapi_kit-0.0.5.dist-info/METADATA,sha256=iThsKiRtntTceqBM3lWJbEYoIkj42855DWtQoKODuOM,38069
55
- strapi_kit-0.0.5.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
56
- strapi_kit-0.0.5.dist-info/licenses/LICENSE,sha256=lN0YUtXlAFBt9MNYr2F0GJEYdprxDOTIqcVhKxMsaTI,1067
57
- strapi_kit-0.0.5.dist-info/RECORD,,
54
+ strapi_kit-0.0.6.dist-info/METADATA,sha256=NZpOUkVKw1o6Umx1IHkVPfybH-n4q6MSKqHf3Oo9qPo,38069
55
+ strapi_kit-0.0.6.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
56
+ strapi_kit-0.0.6.dist-info/licenses/LICENSE,sha256=lN0YUtXlAFBt9MNYr2F0GJEYdprxDOTIqcVhKxMsaTI,1067
57
+ strapi_kit-0.0.6.dist-info/RECORD,,