strapi-kit 0.0.3__py3-none-any.whl → 0.0.5__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.3'
32
- __version_tuple__ = version_tuple = (0, 0, 3)
31
+ __version__ = version = '0.0.5'
32
+ __version_tuple__ = version_tuple = (0, 0, 5)
33
33
 
34
34
  __commit_id__ = commit_id = None
strapi_kit/client/base.py CHANGED
@@ -12,6 +12,7 @@ if TYPE_CHECKING:
12
12
  from ..models.content_type import ContentTypeSchema as CTBContentTypeSchema
13
13
 
14
14
  import httpx
15
+ from pydantic import ValidationError as PydanticValidationError
15
16
  from tenacity import (
16
17
  before_sleep_log,
17
18
  retry,
@@ -75,7 +76,7 @@ class BaseClient:
75
76
  parser: Response parser (defaults to VersionDetectingParser)
76
77
 
77
78
  Raises:
78
- ValueError: If authentication token is invalid
79
+ ConfigurationError: If authentication token is invalid
79
80
  """
80
81
  self.config: ConfigProvider = config
81
82
  self.base_url = config.get_base_url()
@@ -492,9 +493,9 @@ class BaseClient:
492
493
  try:
493
494
  content_type = ContentTypeListItem.model_validate(item)
494
495
  result.append(content_type)
495
- except Exception:
496
+ except PydanticValidationError as e:
496
497
  # Skip malformed items
497
- logger.warning(f"Failed to parse content type: {uid}")
498
+ logger.warning(f"Failed to parse content type: {uid}", exc_info=e)
498
499
  continue
499
500
 
500
501
  return result
@@ -521,9 +522,9 @@ class BaseClient:
521
522
  try:
522
523
  component = ComponentListItem.model_validate(item)
523
524
  result.append(component)
524
- except Exception:
525
+ except PydanticValidationError as e:
525
526
  # Skip malformed items
526
- logger.warning(f"Failed to parse component: {uid}")
527
+ logger.warning(f"Failed to parse component: {uid}", exc_info=e)
527
528
  continue
528
529
 
529
530
  return result
@@ -546,4 +547,10 @@ class BaseClient:
546
547
  from ..models.content_type import ContentTypeSchema as CTBContentTypeSchema
547
548
 
548
549
  data = response_data.get("data", response_data)
549
- return CTBContentTypeSchema.model_validate(data)
550
+ try:
551
+ return CTBContentTypeSchema.model_validate(data)
552
+ except PydanticValidationError as e:
553
+ raise ValidationError(
554
+ "Invalid content type schema response",
555
+ details={"errors": e.errors()},
556
+ ) from e
strapi_kit/utils/uid.py CHANGED
@@ -146,15 +146,26 @@ def api_id_to_singular(api_id: str) -> str:
146
146
  if name.endswith("ies"):
147
147
  return name[:-3] + "y"
148
148
 
149
- # Handle -es for words ending in s, x, z, ch, sh (classes -> class)
149
+ # Handle -zzes specifically
150
+ # Words with single z double it when pluralized: quiz -> quizzes (remove -zes, keep 1 z)
151
+ # Words with double z just add es: buzz -> buzzes, fizz -> fizzes (remove -es, keep zz)
152
+ if name.endswith("zzes"):
153
+ # Common double-z words: buzz, fizz, fuzz, jazz, razz, etc. (pattern: consonant + vowel + zz)
154
+ # Common single-z words that double: quiz, whiz (pattern: vowel + i + z or similar)
155
+ # Heuristic: 4-letter bases (buzz, fizz, jazz, fuzz) become 6-letter plurals
156
+ # 4-letter bases like quiz become 7-letter plurals
157
+ # So length 6 -> likely double-z base (remove -es)
158
+ # length 7+ -> likely single-z base that was doubled (remove -zes)
159
+ if len(name) <= 6:
160
+ return name[:-2] # buzzes -> buzz, fizzes -> fizz
161
+ else:
162
+ return name[:-3] # quizzes -> quiz, whizzes -> whiz
163
+
164
+ # Handle -es for words ending in s, x, z, ch, sh (classes -> class, buses -> bus)
150
165
  if name.endswith("es"):
151
- # Check if removing -es gives a word ending in s, x, z, ch, sh
152
166
  base = name[:-2]
153
167
  if base.endswith(("s", "x", "z", "ch", "sh")):
154
168
  return base
155
- # Also handle -ses, -zes (buses -> bus, quizzes -> quiz)
156
- if name.endswith("ses") or name.endswith("zes"):
157
- return name[:-2]
158
169
 
159
170
  # Handle standard -s removal (articles -> article)
160
171
  if name.endswith("s") and len(name) > 1:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: strapi-kit
3
- Version: 0.0.3
3
+ Version: 0.0.5
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/
@@ -728,6 +728,7 @@ uid_to_endpoint("api::class.class") # "classes"
728
728
  # Convert plural API ID to singular
729
729
  api_id_to_singular("articles") # "article"
730
730
  api_id_to_singular("categories") # "category"
731
+ api_id_to_singular("quizzes") # "quiz" (handles -zzes endings)
731
732
  api_id_to_singular("people") # "person" (handles irregular plurals)
732
733
  api_id_to_singular("children") # "child"
733
734
 
@@ -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=pBZsQt6tlL02W-ri--X_4JCubpAK7jjCSnOmUp_isjc,704
3
+ strapi_kit/_version.py,sha256=YRV1ohn6CdKEhsUOmFFMmr5UTjMv4Ydw3WJGxF2BHBs,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=jITcMtDPNpup60yHAbdn7jzATz-ccQv5l1WuefPJ-00,19567
12
+ strapi_kit/client/base.py,sha256=wzjDSH1bZ8us7iIuSJbi6C7cyqIKbiOaIBunMAiiIa0,19923
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
@@ -50,8 +50,8 @@ strapi_kit/parsers/version_detecting.py,sha256=i6Wh7NSQYPWSv0GR63ZJLuPF6BqFwQ_Y7
50
50
  strapi_kit/utils/__init__.py,sha256=FFSuu9W6Yt1r0OEU55bs9zLz2RuAy0wCVPfzN2BRz7E,823
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
- strapi_kit/utils/uid.py,sha256=XjZ7tTPpiAiVzxylmwCE7aMPZKXhF_uL7ZwFotYLSZs,6102
54
- strapi_kit-0.0.3.dist-info/METADATA,sha256=tKu7Xae8xYsdokePSiZvURE1d4mbSStMDbSNwCZze2E,38005
55
- strapi_kit-0.0.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
56
- strapi_kit-0.0.3.dist-info/licenses/LICENSE,sha256=lN0YUtXlAFBt9MNYr2F0GJEYdprxDOTIqcVhKxMsaTI,1067
57
- strapi_kit-0.0.3.dist-info/RECORD,,
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,,