wp_python 0.1.0__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.
- src/wordpress_api/__init__.py +31 -0
- src/wordpress_api/auth.py +174 -0
- src/wordpress_api/client.py +293 -0
- src/wordpress_api/endpoints/__init__.py +43 -0
- src/wordpress_api/endpoints/application_passwords.py +235 -0
- src/wordpress_api/endpoints/autosaves.py +106 -0
- src/wordpress_api/endpoints/base.py +117 -0
- src/wordpress_api/endpoints/blocks.py +107 -0
- src/wordpress_api/endpoints/categories.py +91 -0
- src/wordpress_api/endpoints/comments.py +127 -0
- src/wordpress_api/endpoints/media.py +164 -0
- src/wordpress_api/endpoints/menus.py +120 -0
- src/wordpress_api/endpoints/pages.py +109 -0
- src/wordpress_api/endpoints/plugins.py +89 -0
- src/wordpress_api/endpoints/post_types.py +61 -0
- src/wordpress_api/endpoints/posts.py +131 -0
- src/wordpress_api/endpoints/revisions.py +121 -0
- src/wordpress_api/endpoints/search.py +81 -0
- src/wordpress_api/endpoints/settings.py +55 -0
- src/wordpress_api/endpoints/statuses.py +56 -0
- src/wordpress_api/endpoints/tags.py +79 -0
- src/wordpress_api/endpoints/taxonomies.py +41 -0
- src/wordpress_api/endpoints/themes.py +51 -0
- src/wordpress_api/endpoints/users.py +129 -0
- src/wordpress_api/exceptions.py +79 -0
- src/wordpress_api/models/__init__.py +49 -0
- src/wordpress_api/models/base.py +65 -0
- src/wordpress_api/models/category.py +41 -0
- src/wordpress_api/models/comment.py +75 -0
- src/wordpress_api/models/media.py +108 -0
- src/wordpress_api/models/menu.py +83 -0
- src/wordpress_api/models/page.py +80 -0
- src/wordpress_api/models/plugin.py +36 -0
- src/wordpress_api/models/post.py +112 -0
- src/wordpress_api/models/settings.py +32 -0
- src/wordpress_api/models/tag.py +38 -0
- src/wordpress_api/models/taxonomy.py +49 -0
- src/wordpress_api/models/theme.py +50 -0
- src/wordpress_api/models/user.py +82 -0
- wp_python-0.1.0.dist-info/METADATA +12 -0
- wp_python-0.1.0.dist-info/RECORD +42 -0
- wp_python-0.1.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"""Users endpoint."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from ..models.user import User, UserCreate, UserUpdate
|
|
8
|
+
from .base import CRUDEndpoint
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class UsersEndpoint(CRUDEndpoint[User]):
|
|
12
|
+
"""Endpoint for managing WordPress users."""
|
|
13
|
+
|
|
14
|
+
_path = "/wp/v2/users"
|
|
15
|
+
_model_class = User
|
|
16
|
+
|
|
17
|
+
def list(
|
|
18
|
+
self,
|
|
19
|
+
page: int = 1,
|
|
20
|
+
per_page: int = 10,
|
|
21
|
+
search: str | None = None,
|
|
22
|
+
order: str = "asc",
|
|
23
|
+
orderby: str = "name",
|
|
24
|
+
roles: str | list[str] | None = None,
|
|
25
|
+
capabilities: str | list[str] | None = None,
|
|
26
|
+
who: str | None = None,
|
|
27
|
+
has_published_posts: bool | str | list[str] | None = None,
|
|
28
|
+
slug: str | list[str] | None = None,
|
|
29
|
+
include: list[int] | None = None,
|
|
30
|
+
exclude: list[int] | None = None,
|
|
31
|
+
**kwargs: Any,
|
|
32
|
+
) -> list[User]:
|
|
33
|
+
"""List users with filtering options."""
|
|
34
|
+
params: dict[str, Any] = {
|
|
35
|
+
"page": page,
|
|
36
|
+
"per_page": per_page,
|
|
37
|
+
"order": order,
|
|
38
|
+
"orderby": orderby,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if search:
|
|
42
|
+
params["search"] = search
|
|
43
|
+
if roles:
|
|
44
|
+
if isinstance(roles, list):
|
|
45
|
+
params["roles"] = ",".join(roles)
|
|
46
|
+
else:
|
|
47
|
+
params["roles"] = roles
|
|
48
|
+
if capabilities:
|
|
49
|
+
if isinstance(capabilities, list):
|
|
50
|
+
params["capabilities"] = ",".join(capabilities)
|
|
51
|
+
else:
|
|
52
|
+
params["capabilities"] = capabilities
|
|
53
|
+
if who:
|
|
54
|
+
params["who"] = who
|
|
55
|
+
if has_published_posts is not None:
|
|
56
|
+
if isinstance(has_published_posts, bool):
|
|
57
|
+
params["has_published_posts"] = has_published_posts
|
|
58
|
+
elif isinstance(has_published_posts, list):
|
|
59
|
+
params["has_published_posts"] = ",".join(has_published_posts)
|
|
60
|
+
else:
|
|
61
|
+
params["has_published_posts"] = has_published_posts
|
|
62
|
+
if slug:
|
|
63
|
+
if isinstance(slug, list):
|
|
64
|
+
params["slug"] = ",".join(slug)
|
|
65
|
+
else:
|
|
66
|
+
params["slug"] = slug
|
|
67
|
+
if include:
|
|
68
|
+
params["include"] = ",".join(map(str, include))
|
|
69
|
+
if exclude:
|
|
70
|
+
params["exclude"] = ",".join(map(str, exclude))
|
|
71
|
+
|
|
72
|
+
params.update(kwargs)
|
|
73
|
+
response = self._get(self._path, params=params)
|
|
74
|
+
return [User.model_validate(item) for item in response]
|
|
75
|
+
|
|
76
|
+
def create(self, data: UserCreate | dict[str, Any]) -> User:
|
|
77
|
+
"""Create a new user."""
|
|
78
|
+
return super().create(data)
|
|
79
|
+
|
|
80
|
+
def update(self, id: int, data: UserUpdate | dict[str, Any]) -> User:
|
|
81
|
+
"""Update an existing user."""
|
|
82
|
+
return super().update(id, data)
|
|
83
|
+
|
|
84
|
+
def me(self, context: str = "view") -> User:
|
|
85
|
+
"""Get the current authenticated user."""
|
|
86
|
+
response = self._get(f"{self._path}/me", params={"context": context})
|
|
87
|
+
return User.model_validate(response)
|
|
88
|
+
|
|
89
|
+
def update_me(self, data: UserUpdate | dict[str, Any]) -> User:
|
|
90
|
+
"""Update the current authenticated user."""
|
|
91
|
+
if isinstance(data, UserUpdate):
|
|
92
|
+
payload = data.model_dump(exclude_none=True)
|
|
93
|
+
else:
|
|
94
|
+
payload = data
|
|
95
|
+
response = self._post(f"{self._path}/me", data=payload)
|
|
96
|
+
return User.model_validate(response)
|
|
97
|
+
|
|
98
|
+
def delete(
|
|
99
|
+
self,
|
|
100
|
+
id: int,
|
|
101
|
+
force: bool = True,
|
|
102
|
+
reassign: int | None = None,
|
|
103
|
+
**kwargs: Any,
|
|
104
|
+
) -> dict[str, Any]:
|
|
105
|
+
"""Delete a user.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
id: User ID to delete.
|
|
109
|
+
force: Must be true (users cannot be trashed).
|
|
110
|
+
reassign: Reassign posts to this user ID.
|
|
111
|
+
"""
|
|
112
|
+
params = {"force": force}
|
|
113
|
+
if reassign is not None:
|
|
114
|
+
params["reassign"] = reassign
|
|
115
|
+
params.update(kwargs)
|
|
116
|
+
return self._delete(f"{self._path}/{id}", params=params)
|
|
117
|
+
|
|
118
|
+
def get_by_slug(self, slug: str) -> User | None:
|
|
119
|
+
"""Get a user by their slug."""
|
|
120
|
+
users = self.list(slug=slug)
|
|
121
|
+
return users[0] if users else None
|
|
122
|
+
|
|
123
|
+
def list_authors(self, **kwargs: Any) -> list[User]:
|
|
124
|
+
"""List users who have published posts."""
|
|
125
|
+
return self.list(has_published_posts=True, **kwargs)
|
|
126
|
+
|
|
127
|
+
def list_by_role(self, role: str, **kwargs: Any) -> list[User]:
|
|
128
|
+
"""List users with a specific role."""
|
|
129
|
+
return self.list(roles=role, **kwargs)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""WordPress API Exception Classes."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class WordPressError(Exception):
|
|
7
|
+
"""Base exception for WordPress API errors."""
|
|
8
|
+
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
message: str,
|
|
12
|
+
status_code: int | None = None,
|
|
13
|
+
error_code: str | None = None,
|
|
14
|
+
data: dict[str, Any] | None = None,
|
|
15
|
+
) -> None:
|
|
16
|
+
super().__init__(message)
|
|
17
|
+
self.message = message
|
|
18
|
+
self.status_code = status_code
|
|
19
|
+
self.error_code = error_code
|
|
20
|
+
self.data = data or {}
|
|
21
|
+
|
|
22
|
+
def __str__(self) -> str:
|
|
23
|
+
parts = [self.message]
|
|
24
|
+
if self.status_code:
|
|
25
|
+
parts.append(f"[HTTP {self.status_code}]")
|
|
26
|
+
if self.error_code:
|
|
27
|
+
parts.append(f"[{self.error_code}]")
|
|
28
|
+
return " ".join(parts)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class AuthenticationError(WordPressError):
|
|
32
|
+
"""Authentication failed."""
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class NotFoundError(WordPressError):
|
|
37
|
+
"""Resource not found."""
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ValidationError(WordPressError):
|
|
42
|
+
"""Validation error in request data."""
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class RateLimitError(WordPressError):
|
|
47
|
+
"""Rate limit exceeded."""
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ServerError(WordPressError):
|
|
52
|
+
"""Server-side error."""
|
|
53
|
+
pass
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class PermissionError(WordPressError):
|
|
57
|
+
"""Permission denied."""
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def raise_for_status(status_code: int, response_data: dict[str, Any]) -> None:
|
|
62
|
+
"""Raise appropriate exception based on status code."""
|
|
63
|
+
message = response_data.get("message", "Unknown error")
|
|
64
|
+
error_code = response_data.get("code", "unknown_error")
|
|
65
|
+
|
|
66
|
+
if status_code == 401:
|
|
67
|
+
raise AuthenticationError(message, status_code, error_code, response_data)
|
|
68
|
+
elif status_code == 403:
|
|
69
|
+
raise PermissionError(message, status_code, error_code, response_data)
|
|
70
|
+
elif status_code == 404:
|
|
71
|
+
raise NotFoundError(message, status_code, error_code, response_data)
|
|
72
|
+
elif status_code == 400:
|
|
73
|
+
raise ValidationError(message, status_code, error_code, response_data)
|
|
74
|
+
elif status_code == 429:
|
|
75
|
+
raise RateLimitError(message, status_code, error_code, response_data)
|
|
76
|
+
elif status_code >= 500:
|
|
77
|
+
raise ServerError(message, status_code, error_code, response_data)
|
|
78
|
+
elif status_code >= 400:
|
|
79
|
+
raise WordPressError(message, status_code, error_code, response_data)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Pydantic models for WordPress API responses."""
|
|
2
|
+
|
|
3
|
+
from .post import Post, PostCreate, PostUpdate, PostStatus, PostFormat
|
|
4
|
+
from .page import Page, PageCreate, PageUpdate
|
|
5
|
+
from .media import Media, MediaCreate, MediaUpdate, MediaType
|
|
6
|
+
from .user import User, UserCreate, UserUpdate, UserRole
|
|
7
|
+
from .comment import Comment, CommentCreate, CommentUpdate, CommentStatus
|
|
8
|
+
from .category import Category, CategoryCreate, CategoryUpdate
|
|
9
|
+
from .tag import Tag, TagCreate, TagUpdate
|
|
10
|
+
from .taxonomy import Taxonomy
|
|
11
|
+
from .settings import Settings
|
|
12
|
+
from .plugin import Plugin
|
|
13
|
+
from .theme import Theme
|
|
14
|
+
from .menu import Menu, MenuItem
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"Post",
|
|
18
|
+
"PostCreate",
|
|
19
|
+
"PostUpdate",
|
|
20
|
+
"PostStatus",
|
|
21
|
+
"PostFormat",
|
|
22
|
+
"Page",
|
|
23
|
+
"PageCreate",
|
|
24
|
+
"PageUpdate",
|
|
25
|
+
"Media",
|
|
26
|
+
"MediaCreate",
|
|
27
|
+
"MediaUpdate",
|
|
28
|
+
"MediaType",
|
|
29
|
+
"User",
|
|
30
|
+
"UserCreate",
|
|
31
|
+
"UserUpdate",
|
|
32
|
+
"UserRole",
|
|
33
|
+
"Comment",
|
|
34
|
+
"CommentCreate",
|
|
35
|
+
"CommentUpdate",
|
|
36
|
+
"CommentStatus",
|
|
37
|
+
"Category",
|
|
38
|
+
"CategoryCreate",
|
|
39
|
+
"CategoryUpdate",
|
|
40
|
+
"Tag",
|
|
41
|
+
"TagCreate",
|
|
42
|
+
"TagUpdate",
|
|
43
|
+
"Taxonomy",
|
|
44
|
+
"Settings",
|
|
45
|
+
"Plugin",
|
|
46
|
+
"Theme",
|
|
47
|
+
"Menu",
|
|
48
|
+
"MenuItem",
|
|
49
|
+
]
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""Base models and utilities."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, ConfigDict, field_validator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class WordPressModel(BaseModel):
|
|
10
|
+
"""Base model for WordPress objects."""
|
|
11
|
+
|
|
12
|
+
model_config = ConfigDict(
|
|
13
|
+
populate_by_name=True,
|
|
14
|
+
extra="allow",
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class RenderedContent(BaseModel):
|
|
19
|
+
"""Content with rendered HTML."""
|
|
20
|
+
|
|
21
|
+
rendered: str = ""
|
|
22
|
+
raw: str | None = None
|
|
23
|
+
protected: bool = False
|
|
24
|
+
|
|
25
|
+
model_config = ConfigDict(extra="allow")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class WPLink(BaseModel):
|
|
29
|
+
"""WordPress REST API link."""
|
|
30
|
+
|
|
31
|
+
href: str
|
|
32
|
+
embeddable: bool = False
|
|
33
|
+
|
|
34
|
+
model_config = ConfigDict(extra="allow")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class WPLinks(BaseModel):
|
|
38
|
+
"""Collection of WordPress REST API links."""
|
|
39
|
+
|
|
40
|
+
self_: list[WPLink] | None = None
|
|
41
|
+
collection: list[WPLink] | None = None
|
|
42
|
+
about: list[WPLink] | None = None
|
|
43
|
+
author: list[WPLink] | None = None
|
|
44
|
+
replies: list[WPLink] | None = None
|
|
45
|
+
version_history: list[WPLink] | None = None
|
|
46
|
+
predecessor_version: list[WPLink] | None = None
|
|
47
|
+
wp_attachment: list[WPLink] | None = None
|
|
48
|
+
wp_term: list[WPLink] | None = None
|
|
49
|
+
curies: list[WPLink] | None = None
|
|
50
|
+
|
|
51
|
+
model_config = ConfigDict(extra="allow", populate_by_name=True)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def parse_datetime(value: Any) -> datetime | None:
|
|
55
|
+
"""Parse WordPress datetime string."""
|
|
56
|
+
if value is None:
|
|
57
|
+
return None
|
|
58
|
+
if isinstance(value, datetime):
|
|
59
|
+
return value
|
|
60
|
+
if isinstance(value, str):
|
|
61
|
+
try:
|
|
62
|
+
return datetime.fromisoformat(value.replace("Z", "+00:00"))
|
|
63
|
+
except ValueError:
|
|
64
|
+
return None
|
|
65
|
+
return None
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Category models."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from .base import WordPressModel
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Category(WordPressModel):
|
|
11
|
+
"""WordPress Category object."""
|
|
12
|
+
|
|
13
|
+
id: int
|
|
14
|
+
count: int = 0
|
|
15
|
+
description: str = ""
|
|
16
|
+
link: str = ""
|
|
17
|
+
name: str = ""
|
|
18
|
+
slug: str = ""
|
|
19
|
+
taxonomy: str = "category"
|
|
20
|
+
parent: int = 0
|
|
21
|
+
meta: dict[str, Any] = Field(default_factory=dict)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class CategoryCreate(WordPressModel):
|
|
25
|
+
"""Data for creating a new category."""
|
|
26
|
+
|
|
27
|
+
name: str
|
|
28
|
+
description: str | None = None
|
|
29
|
+
slug: str | None = None
|
|
30
|
+
parent: int | None = None
|
|
31
|
+
meta: dict[str, Any] | None = None
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class CategoryUpdate(WordPressModel):
|
|
35
|
+
"""Data for updating a category."""
|
|
36
|
+
|
|
37
|
+
name: str | None = None
|
|
38
|
+
description: str | None = None
|
|
39
|
+
slug: str | None = None
|
|
40
|
+
parent: int | None = None
|
|
41
|
+
meta: dict[str, Any] | None = None
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Comment models."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from pydantic import Field, field_validator
|
|
8
|
+
|
|
9
|
+
from .base import WordPressModel, RenderedContent, parse_datetime
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CommentStatus(str, Enum):
|
|
13
|
+
"""Comment status options."""
|
|
14
|
+
|
|
15
|
+
APPROVED = "approved"
|
|
16
|
+
HOLD = "hold"
|
|
17
|
+
SPAM = "spam"
|
|
18
|
+
TRASH = "trash"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Comment(WordPressModel):
|
|
22
|
+
"""WordPress Comment object."""
|
|
23
|
+
|
|
24
|
+
id: int
|
|
25
|
+
post: int = 0
|
|
26
|
+
parent: int = 0
|
|
27
|
+
author: int = 0
|
|
28
|
+
author_name: str = ""
|
|
29
|
+
author_email: str = ""
|
|
30
|
+
author_url: str = ""
|
|
31
|
+
author_ip: str = ""
|
|
32
|
+
author_user_agent: str = ""
|
|
33
|
+
date: datetime | None = None
|
|
34
|
+
date_gmt: datetime | None = None
|
|
35
|
+
content: RenderedContent | None = None
|
|
36
|
+
link: str = ""
|
|
37
|
+
status: str = "approved"
|
|
38
|
+
type: str = "comment"
|
|
39
|
+
author_avatar_urls: dict[str, str] = Field(default_factory=dict)
|
|
40
|
+
meta: dict[str, Any] = Field(default_factory=dict)
|
|
41
|
+
|
|
42
|
+
@field_validator("date", "date_gmt", mode="before")
|
|
43
|
+
@classmethod
|
|
44
|
+
def parse_dates(cls, v: Any) -> datetime | None:
|
|
45
|
+
return parse_datetime(v)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class CommentCreate(WordPressModel):
|
|
49
|
+
"""Data for creating a new comment."""
|
|
50
|
+
|
|
51
|
+
post: int
|
|
52
|
+
content: str
|
|
53
|
+
parent: int | None = None
|
|
54
|
+
author: int | None = None
|
|
55
|
+
author_name: str | None = None
|
|
56
|
+
author_email: str | None = None
|
|
57
|
+
author_url: str | None = None
|
|
58
|
+
status: CommentStatus | None = None
|
|
59
|
+
meta: dict[str, Any] | None = None
|
|
60
|
+
date: datetime | str | None = None
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class CommentUpdate(WordPressModel):
|
|
64
|
+
"""Data for updating a comment."""
|
|
65
|
+
|
|
66
|
+
content: str | None = None
|
|
67
|
+
post: int | None = None
|
|
68
|
+
parent: int | None = None
|
|
69
|
+
author: int | None = None
|
|
70
|
+
author_name: str | None = None
|
|
71
|
+
author_email: str | None = None
|
|
72
|
+
author_url: str | None = None
|
|
73
|
+
status: CommentStatus | None = None
|
|
74
|
+
meta: dict[str, Any] | None = None
|
|
75
|
+
date: datetime | str | None = None
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""Media models."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from pydantic import Field, field_validator
|
|
8
|
+
|
|
9
|
+
from .base import WordPressModel, RenderedContent, parse_datetime
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MediaType(str, Enum):
|
|
13
|
+
"""Media type options."""
|
|
14
|
+
|
|
15
|
+
IMAGE = "image"
|
|
16
|
+
FILE = "file"
|
|
17
|
+
AUDIO = "audio"
|
|
18
|
+
VIDEO = "video"
|
|
19
|
+
APPLICATION = "application"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class MediaSize(WordPressModel):
|
|
23
|
+
"""Individual media size details."""
|
|
24
|
+
|
|
25
|
+
file: str = ""
|
|
26
|
+
width: int = 0
|
|
27
|
+
height: int = 0
|
|
28
|
+
mime_type: str = ""
|
|
29
|
+
source_url: str = ""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class MediaDetails(WordPressModel):
|
|
33
|
+
"""Media file details."""
|
|
34
|
+
|
|
35
|
+
width: int = 0
|
|
36
|
+
height: int = 0
|
|
37
|
+
file: str = ""
|
|
38
|
+
filesize: int = 0
|
|
39
|
+
sizes: dict[str, MediaSize] = Field(default_factory=dict)
|
|
40
|
+
image_meta: dict[str, Any] = Field(default_factory=dict)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class Media(WordPressModel):
|
|
44
|
+
"""WordPress Media object."""
|
|
45
|
+
|
|
46
|
+
id: int
|
|
47
|
+
date: datetime | None = None
|
|
48
|
+
date_gmt: datetime | None = None
|
|
49
|
+
guid: RenderedContent | None = None
|
|
50
|
+
modified: datetime | None = None
|
|
51
|
+
modified_gmt: datetime | None = None
|
|
52
|
+
slug: str = ""
|
|
53
|
+
status: str = "inherit"
|
|
54
|
+
type: str = "attachment"
|
|
55
|
+
link: str = ""
|
|
56
|
+
title: RenderedContent | None = None
|
|
57
|
+
author: int = 0
|
|
58
|
+
comment_status: str = "open"
|
|
59
|
+
ping_status: str = "closed"
|
|
60
|
+
template: str = ""
|
|
61
|
+
meta: dict[str, Any] = Field(default_factory=dict)
|
|
62
|
+
description: RenderedContent | None = None
|
|
63
|
+
caption: RenderedContent | None = None
|
|
64
|
+
alt_text: str = ""
|
|
65
|
+
media_type: str = ""
|
|
66
|
+
mime_type: str = ""
|
|
67
|
+
media_details: MediaDetails | None = None
|
|
68
|
+
post: int | None = None
|
|
69
|
+
source_url: str = ""
|
|
70
|
+
|
|
71
|
+
@field_validator("date", "date_gmt", "modified", "modified_gmt", mode="before")
|
|
72
|
+
@classmethod
|
|
73
|
+
def parse_dates(cls, v: Any) -> datetime | None:
|
|
74
|
+
return parse_datetime(v)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class MediaCreate(WordPressModel):
|
|
78
|
+
"""Data for creating/uploading new media."""
|
|
79
|
+
|
|
80
|
+
title: str | None = None
|
|
81
|
+
caption: str | None = None
|
|
82
|
+
alt_text: str | None = None
|
|
83
|
+
description: str | None = None
|
|
84
|
+
post: int | None = None
|
|
85
|
+
author: int | None = None
|
|
86
|
+
comment_status: str | None = None
|
|
87
|
+
ping_status: str | None = None
|
|
88
|
+
meta: dict[str, Any] | None = None
|
|
89
|
+
slug: str | None = None
|
|
90
|
+
status: str | None = None
|
|
91
|
+
date: datetime | str | None = None
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class MediaUpdate(WordPressModel):
|
|
95
|
+
"""Data for updating media."""
|
|
96
|
+
|
|
97
|
+
title: str | None = None
|
|
98
|
+
caption: str | None = None
|
|
99
|
+
alt_text: str | None = None
|
|
100
|
+
description: str | None = None
|
|
101
|
+
post: int | None = None
|
|
102
|
+
author: int | None = None
|
|
103
|
+
comment_status: str | None = None
|
|
104
|
+
ping_status: str | None = None
|
|
105
|
+
meta: dict[str, Any] | None = None
|
|
106
|
+
slug: str | None = None
|
|
107
|
+
status: str | None = None
|
|
108
|
+
date: datetime | str | None = None
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""Menu models."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from .base import WordPressModel
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MenuItem(WordPressModel):
|
|
11
|
+
"""WordPress Menu Item object."""
|
|
12
|
+
|
|
13
|
+
id: int
|
|
14
|
+
title: str = ""
|
|
15
|
+
status: str = "publish"
|
|
16
|
+
url: str = ""
|
|
17
|
+
attr_title: str = ""
|
|
18
|
+
description: str = ""
|
|
19
|
+
type: str = "custom"
|
|
20
|
+
type_label: str = ""
|
|
21
|
+
object: str = "custom"
|
|
22
|
+
object_id: int = 0
|
|
23
|
+
parent: int = 0
|
|
24
|
+
menu_order: int = 0
|
|
25
|
+
target: str = ""
|
|
26
|
+
classes: list[str] = Field(default_factory=list)
|
|
27
|
+
xfn: list[str] = Field(default_factory=list)
|
|
28
|
+
invalid: bool = False
|
|
29
|
+
menus: int = 0
|
|
30
|
+
meta: dict[str, Any] = Field(default_factory=dict)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class Menu(WordPressModel):
|
|
34
|
+
"""WordPress Navigation Menu object."""
|
|
35
|
+
|
|
36
|
+
id: int
|
|
37
|
+
name: str = ""
|
|
38
|
+
slug: str = ""
|
|
39
|
+
description: str = ""
|
|
40
|
+
count: int = 0
|
|
41
|
+
auto_add: bool = False
|
|
42
|
+
locations: list[str] = Field(default_factory=list)
|
|
43
|
+
meta: dict[str, Any] = Field(default_factory=dict)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class MenuItemCreate(WordPressModel):
|
|
47
|
+
"""Data for creating a menu item."""
|
|
48
|
+
|
|
49
|
+
title: str
|
|
50
|
+
url: str | None = None
|
|
51
|
+
status: str = "publish"
|
|
52
|
+
attr_title: str | None = None
|
|
53
|
+
description: str | None = None
|
|
54
|
+
type: str = "custom"
|
|
55
|
+
object: str | None = None
|
|
56
|
+
object_id: int | None = None
|
|
57
|
+
parent: int | None = None
|
|
58
|
+
menu_order: int | None = None
|
|
59
|
+
target: str | None = None
|
|
60
|
+
classes: list[str] | None = None
|
|
61
|
+
xfn: list[str] | None = None
|
|
62
|
+
menus: int | None = None
|
|
63
|
+
meta: dict[str, Any] | None = None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class MenuItemUpdate(WordPressModel):
|
|
67
|
+
"""Data for updating a menu item."""
|
|
68
|
+
|
|
69
|
+
title: str | None = None
|
|
70
|
+
url: str | None = None
|
|
71
|
+
status: str | None = None
|
|
72
|
+
attr_title: str | None = None
|
|
73
|
+
description: str | None = None
|
|
74
|
+
type: str | None = None
|
|
75
|
+
object: str | None = None
|
|
76
|
+
object_id: int | None = None
|
|
77
|
+
parent: int | None = None
|
|
78
|
+
menu_order: int | None = None
|
|
79
|
+
target: str | None = None
|
|
80
|
+
classes: list[str] | None = None
|
|
81
|
+
xfn: list[str] | None = None
|
|
82
|
+
menus: int | None = None
|
|
83
|
+
meta: dict[str, Any] | None = None
|