| Name | py-dmmjp JSON |
| Version |
0.0.11
JSON |
| download |
| home_page | None |
| Summary | A Python client library for the DMM API |
| upload_time | 2025-10-21 05:04:45 |
| maintainer | None |
| docs_url | None |
| author | None |
| requires_python | >=3.8 |
| license | MIT License
Copyright (c) 2025 Richard Nguyen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
|
| keywords |
dmm
api
client
digital
media
affiliate
|
| VCS |
 |
| bugtrack_url |
|
| requirements |
requests
typing-extensions
|
| Travis-CI |
No Travis.
|
| coveralls test coverage |
No coveralls.
|
# py-dmmjp
[](https://badge.fury.io/py/py-dmmjp)
[](https://pypi.org/project/py-dmmjp/)
[](https://codecov.io/github/richardnguyen99/py-dmmjp)
[](https://opensource.org/licenses/MIT)
[](https://github.com/psf/black)
[](https://mypy-lang.org/)
A Python client library for the DMM (Digital Media Mart) API with full type hints support.
## Features
- [x] **Product Search**: Search for products with various filters and parameters
- [x] **Product Details**: Retrieve detailed information about specific products
- [x] **Genre/Category Support**: Browse and filter by categories and genres
- [x] **Type Safety**: Full type hints support with mypy validation
- [x] **Well Tested**: Comprehensive test suite with pytest
- [x] **Well Documented**: Complete API documentation and examples
## Installation
Install py-dmmjp using pip:
```bash
pip install py-dmmjp
```
For development installation with all optional dependencies:
```bash
pip install py-dmmjp[dev]
```
## Quick Start
```python
from py_dmmjp import DMMClient
def main() -> None:
dmm_client = DMMClient(api_key="your_api_key", affiliate_id="your_affiliate_key")
print(dmm_client)
series = dmm_client.get_series(43, hits=5)
for s in series:
print(f"{s.name}")
print(f" - ID: {s.series_id}")
print(f" - Ruby: {s.ruby}")
```
## API Reference
### DMMClient
The main client class for interacting with the DMM API.
#### Constructor
```python
DMMClient(
api_key: str,
affiliate_id: str,
timeout: int = 10,
)
```
**Parameters:**
- `api_key`: Your DMM API key
- `affiliate_id`: Your DMM Affiliate key (required)
- `timeout`: Maximum seconds the client should wait for a response (optional)
### Methods
#### get_products
```python
get_products(**kwargs: Unpack[ProductSearchParams]) -> List[Product]
```
Retrieve product information from the DMM API. This method fetches products and returns a list of Product objects, handling the API response internally.
Example:
```python
products = client.get_products(
site="FANZA",
service="digital",
floor="videoa",
keyword="AIKA",
hits=10,
sort="review"
)
```
Reference: `docs/products.md`
#### get_product_by_cid
```python
get_product_by_cid(cid: str, site: Literal["FANZA", "DMM.com"]) -> Optional[Product]
```
Retrieve a single product by its content ID (cid).
Example:
```python
product = client.get_product_by_cid(cid="ABP-477", site="FANZA")
```
Reference: `docs/products.md`
#### get_product_by_product_id
```python
get_product_by_product_id(product_id: str, site: Literal["FANZA", "DMM.com"]) -> Optional[Product]
```
Retrieve a single product by its product ID such as "ABP-477", "MIRD-127", etc.
Example:
```python
product = client.get_product_by_product_id(product_id="ABP-477", site="FANZA")
```
Reference: `docs/products.md`
#### get_floors
```python
get_floors() -> List[Site]
```
Retrieve the floor list from the DMM API. This method fetches all available floors, sites, and services.
Example:
```python
floors = client.get_floors()
```
Reference: `docs/development.md`
#### get_actresses
```python
get_actresses(**kwargs: Unpack[ActressSearchParams]) -> List[Actress]
```
Retrieve actress information from the DMM API. This method fetches actresses and returns a list of Actress objects.
Example:
```python
actresses = client.get_actresses(
keyword="あさみ",
gte_bust=80,
lte_bust=100,
hits=10,
sort="bust"
)
```
Reference: `docs/actresses.md`
#### get_genres
```python
get_genres(floor_id: int, **kwargs: Unpack[GenreSearchParams]) -> List[Genre]
```
Retrieve genre information from the DMM API based on floor ID.
Example:
```python
genres = client.get_genres(
floor_id=43,
initial="き",
hits=10
)
```
Reference: `docs/development.md`
#### get_makers
```python
get_makers(floor_id: int, **kwargs: Unpack[MakerSearchParams]) -> List[Maker]
```
Retrieve maker information from the DMM API based on floor ID.
Example:
```python
makers = client.get_makers(
floor_id=43,
initial="あ",
hits=10
)
```
Reference: `docs/makers.md`
#### get_series
```python
get_series(floor_id: int, **kwargs: Unpack[SeriesSearchParams]) -> List[Series]
```
Retrieve series information from the DMM API based on floor ID.
Example:
```python
series = client.get_series(
floor_id=27,
initial="お",
hits=10
)
```
Reference: `docs/development.md`
#### get_authors
```python
get_authors(floor_id: int, **kwargs: Unpack[AuthorSearchParams]) -> List[Author]
```
Retrieve author information from the DMM API based on floor ID.
Example:
```python
authors = client.get_authors(
floor_id=27,
initial="う",
hits=10
)
```
Reference: `docs/development.md`
### Data Models
#### Product
The `Product` dataclass represents detailed product information from the DMM API.
**Key Attributes:**
- `content_id` (str): Content ID for the product
- `product_id` (str): Product ID (e.g., "ABP-477", "MIRD-127")
- `title` (str): Product title in Japanese
- `volume` (str): Volume or episode information
- `URL` (str): Product detail page URL with affiliate tracking
- `affiliate_URL` (str): Affiliate link URL
- `imageURL` (ProductImageURL): Product images in multiple sizes
- `prices` (ProductPrices): Pricing information
- `date` (str): Release date in YYYY-MM-DD format
- `iteminfo` (ProductItemInfo): Detailed product metadata (genres, series, maker, etc.)
**Usage Example:**
```python
products = client.get_products(site="FANZA", service="digital", floor="videoa", keyword="AIKA", hits=5)
for product in products:
print(f"Title: {product.title}")
print(f"Product ID: {product.product_id}")
print(f"Price: {product.prices.price if product.prices else 'N/A'}")
```
Reference: `docs/products.md`
#### Floor
The `Floor`, `Service`, and `Site` dataclasses represent the hierarchical structure of DMM's content organization.
**Site** - Top-level organization:
- `name` (str): Site name (e.g., "DMM.com(一般)", "FANZA(アダルト)")
- `code` (str): Site code (e.g., "DMM.com", "FANZA")
- `services` (List[Service]): List of services available on this site
**Service** - Mid-level organization:
- `name` (str): Service name (e.g., "動画", "通販")
- `code` (str): Service code (e.g., "digital", "mono")
- `floors` (List[Floor]): List of floors within this service
**Floor** - Specific content category:
- `id` (str): Floor ID (e.g., "6", "43")
- `name` (str): Floor name (e.g., "映画・ドラマ", "ビデオ")
- `code` (str): Floor code (e.g., "cinema", "videoa")
**Usage Example:**
```python
floors = client.get_floors()
for site in floors:
print(f"Site: {site.name}")
for service in site.services:
print(f" Service: {service.name}")
for floor in service.floors:
print(f" Floor: {floor.name} (ID: {floor.id})")
```
Reference: `docs/development.md`
#### Actress
The `Actress` dataclass represents actress information from the DMM Actress Search API.
**Key Attributes:**
- `id` (int): Actress ID
- `name` (str): Actress name in Japanese
- `ruby` (Optional[str]): Name phonetic reading
- `bust` (Optional[int]): Bust measurement in cm
- `cup` (Optional[str]): Cup size (e.g., "H", "B", "C")
- `waist` (Optional[int]): Waist measurement in cm
- `hip` (Optional[int]): Hip measurement in cm
- `height` (Optional[int]): Height in cm
- `birthday` (Optional[str]): Birthday in YYYY-MM-DD format
- `blood_type` (Optional[str]): Blood type
- `hobby` (Optional[str]): Hobbies and interests
- `prefectures` (Optional[str]): Birthplace prefecture
- `image_url` (Optional[ActressImageURL]): Image URLs (small, large)
- `list_url` (Optional[ActressListURL]): Content list URLs (digital, monthly, mono)
**Usage Example:**
```python
actresses = client.get_actresses(keyword="あさみ", gte_bust=80, hits=10)
for actress in actresses:
print(f"Name: {actress.name} ({actress.ruby})")
print(f"Measurements: B{actress.bust} W{actress.waist} H{actress.hip}")
print(f"Height: {actress.height}cm")
```
Reference: `docs/actresses.md`
#### Maker
The `Maker` dataclass represents maker (studio/publisher) information from the DMM Maker Search API.
**Attributes:**
- `maker_id` (str): Maker ID (e.g., "1509", "45556")
- `name` (str): Maker name (e.g., "ムーディーズ", "アタッカーズ")
- `ruby` (str): Maker name phonetic reading
- `list_url` (str): List page URL with affiliate ID
**Usage Example:**
```python
makers = client.get_makers(floor_id=43, initial="あ", hits=10)
for maker in makers:
print(f"Maker: {maker.name}")
print(f"ID: {maker.maker_id}")
print(f"Ruby: {maker.ruby}")
print(f"URL: {maker.list_url}")
```
Reference: `docs/makers.md`
#### Series
The `Series` dataclass represents series information from the DMM Series Search API.
**Attributes:**
- `series_id` (str): Series ID (e.g., "62226", "105331")
- `name` (str): Series name (e.g., "ARIA", "おあいにくさま二ノ宮くん")
- `ruby` (str): Series name phonetic reading
- `list_url` (str): List page URL with affiliate ID
**Usage Example:**
```python
series = client.get_series(floor_id=27, initial="お", hits=10)
for s in series:
print(f"Series: {s.name}")
print(f"ID: {s.series_id}")
print(f"Ruby: {s.ruby}")
```
Reference: `docs/development.md`
#### Genre
The `Genre` dataclass represents genre/category information from the DMM Genre Search API.
**Attributes:**
- `genre_id` (str): Genre ID (e.g., "2001", "73115")
- `name` (str): Genre name (e.g., "巨乳", "キャラクター")
- `ruby` (str): Genre name phonetic reading
- `list_url` (str): List page URL with affiliate ID
**Usage Example:**
```python
genres = client.get_genres(floor_id=43, initial="き", hits=10)
for genre in genres:
print(f"Genre: {genre.name}")
print(f"ID: {genre.genre_id}")
print(f"Ruby: {genre.ruby}")
```
Reference: `docs/development.md`
#### Author
The `Author` dataclass represents author information from the DMM Author Search API.
**Attributes:**
- `author_id` (str): Author ID (e.g., "21414", "182179")
- `name` (str): Author name (e.g., "ヴィクトル・ユゴー", "ウィクセル")
- `ruby` (str): Author name phonetic reading
- `list_url` (str): List page URL with affiliate ID
- `another_name` (str): Author alias/another name
**Usage Example:**
```python
authors = client.get_authors(floor_id=27, initial="う", hits=10)
for author in authors:
print(f"Author: {author.name}")
print(f"ID: {author.author_id}")
print(f"Ruby: {author.ruby}")
if author.another_name:
print(f"Also known as: {author.another_name}")
```
Reference: `docs/development.md`
### Exception Handling
The library provides custom exceptions for better error handling:
#### DMMError
Base exception class for all py-dmm errors.
**Attributes:**
- `message` (str): The error message
- `details` (Optional[Any]): Additional error details
**Usage Example:**
```python
from py_dmmjp.exceptions import DMMError
try:
# Your code here
pass
except DMMError as e:
print(f"Error: {e.message}")
if e.details:
print(f"Details: {e.details}")
```
#### DMMAPIError
Exception raised for API-related errors. Inherits from `DMMError`.
**Attributes:**
- `message` (str): The error message
- `status_code` (Optional[int]): HTTP status code of the failed request
- `response_data` (Optional[Any]): Raw response data from the API
**Usage Example:**
```python
from py_dmmjp.exceptions import DMMAPIError
try:
products = client.get_products(site="FANZA", service="digital", floor="videoa")
except DMMAPIError as e:
print(f"API Error: {e.message}")
print(f"Status Code: {e.status_code}")
print(f"Response: {e.response_data}")
```
#### DMMAuthError
Exception raised for authentication-related errors. Inherits from `DMMError`.
**Attributes:**
- `message` (str): The error message (default: "Authentication failed")
**Usage Example:**
```python
from py_dmmjp import DMMClient
from py_dmmjp.exceptions import DMMAuthError
try:
client = DMMClient(api_key="invalid_key", affiliate_id="invalid_id")
products = client.get_products(site="FANZA")
except DMMAuthError as e:
print(f"Authentication Error: {e.message}")
```
## Development
### Setup Development Environment
1. Clone the repository:
```bash
git clone https://github.com/richardnguyen99/py-dmmjp.git
cd py-dmmjp
```
2. Install development dependencies:
```bash
pip install -r requirements-dev.txt
```
3. Install pre-commit hooks:
```bash
pre-commit install
```
### Running Tests
```bash
# Run all tests
pytest
# Run tests with coverage
pytest --cov=py_dmm
# Run specific test file
pytest tests/test_series_dvd.py
```
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to:
1. Update tests as appropriate
2. Follow the existing code style (black + isort)
3. Add type hints to new code
4. Update documentation for new features
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Changelog
See [CHANGELOG.md](CHANGELOG.md) for a detailed history of changes.
## Support
- 📖 [Documentation](https://py-dmmjp.readthedocs.io/)
- 🐛 [Issue Tracker](https://github.com/richardnguyen99/py-dmmjp/issues)
- 💬 [Discussions](https://github.com/richardnguyen99/py-dmmjp/discussions)
Raw data
{
"_id": null,
"home_page": null,
"name": "py-dmmjp",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "Richard Nguyen <richard@richardhnguyen.com>",
"keywords": "dmm, api, client, digital, media, affiliate",
"author": null,
"author_email": "Richard Nguyen <richard@richardhnguyen.com>",
"download_url": "https://files.pythonhosted.org/packages/6b/ff/010edb22062ba00e34d1b999964b3cf53938cb0960098414c3fa7cf8ad57/py_dmmjp-0.0.11.tar.gz",
"platform": null,
"description": "# py-dmmjp\n\n[](https://badge.fury.io/py/py-dmmjp)\n[](https://pypi.org/project/py-dmmjp/)\n[](https://codecov.io/github/richardnguyen99/py-dmmjp)\n[](https://opensource.org/licenses/MIT)\n[](https://github.com/psf/black)\n[](https://mypy-lang.org/)\n\nA Python client library for the DMM (Digital Media Mart) API with full type hints support.\n\n## Features\n\n- [x] **Product Search**: Search for products with various filters and parameters\n- [x] **Product Details**: Retrieve detailed information about specific products\n- [x] **Genre/Category Support**: Browse and filter by categories and genres\n- [x] **Type Safety**: Full type hints support with mypy validation\n- [x] **Well Tested**: Comprehensive test suite with pytest\n- [x] **Well Documented**: Complete API documentation and examples\n\n## Installation\n\nInstall py-dmmjp using pip:\n\n```bash\npip install py-dmmjp\n```\n\nFor development installation with all optional dependencies:\n\n```bash\npip install py-dmmjp[dev]\n```\n\n## Quick Start\n\n```python\nfrom py_dmmjp import DMMClient\n\ndef main() -> None:\n dmm_client = DMMClient(api_key=\"your_api_key\", affiliate_id=\"your_affiliate_key\")\n\n print(dmm_client)\n\n series = dmm_client.get_series(43, hits=5)\n\n for s in series:\n print(f\"{s.name}\")\n print(f\" - ID: {s.series_id}\")\n print(f\" - Ruby: {s.ruby}\")\n```\n\n## API Reference\n\n### DMMClient\n\nThe main client class for interacting with the DMM API.\n\n#### Constructor\n\n```python\nDMMClient(\n api_key: str,\n affiliate_id: str,\n timeout: int = 10,\n)\n```\n\n**Parameters:**\n\n- `api_key`: Your DMM API key\n- `affiliate_id`: Your DMM Affiliate key (required)\n- `timeout`: Maximum seconds the client should wait for a response (optional)\n\n### Methods\n\n#### get_products\n\n```python\nget_products(**kwargs: Unpack[ProductSearchParams]) -> List[Product]\n```\n\nRetrieve product information from the DMM API. This method fetches products and returns a list of Product objects, handling the API response internally.\n\nExample:\n\n```python\nproducts = client.get_products(\n site=\"FANZA\",\n service=\"digital\",\n floor=\"videoa\",\n keyword=\"AIKA\",\n hits=10,\n sort=\"review\"\n)\n```\n\nReference: `docs/products.md`\n\n#### get_product_by_cid\n\n```python\nget_product_by_cid(cid: str, site: Literal[\"FANZA\", \"DMM.com\"]) -> Optional[Product]\n```\n\nRetrieve a single product by its content ID (cid).\n\nExample:\n\n```python\nproduct = client.get_product_by_cid(cid=\"ABP-477\", site=\"FANZA\")\n```\n\nReference: `docs/products.md`\n\n#### get_product_by_product_id\n\n```python\nget_product_by_product_id(product_id: str, site: Literal[\"FANZA\", \"DMM.com\"]) -> Optional[Product]\n```\n\nRetrieve a single product by its product ID such as \"ABP-477\", \"MIRD-127\", etc.\n\nExample:\n\n```python\nproduct = client.get_product_by_product_id(product_id=\"ABP-477\", site=\"FANZA\")\n```\n\nReference: `docs/products.md`\n\n#### get_floors\n\n```python\nget_floors() -> List[Site]\n```\n\nRetrieve the floor list from the DMM API. This method fetches all available floors, sites, and services.\n\nExample:\n\n```python\nfloors = client.get_floors()\n```\n\nReference: `docs/development.md`\n\n#### get_actresses\n\n```python\nget_actresses(**kwargs: Unpack[ActressSearchParams]) -> List[Actress]\n```\n\nRetrieve actress information from the DMM API. This method fetches actresses and returns a list of Actress objects.\n\nExample:\n\n```python\nactresses = client.get_actresses(\n keyword=\"\u3042\u3055\u307f\",\n gte_bust=80,\n lte_bust=100,\n hits=10,\n sort=\"bust\"\n)\n```\n\nReference: `docs/actresses.md`\n\n#### get_genres\n\n```python\nget_genres(floor_id: int, **kwargs: Unpack[GenreSearchParams]) -> List[Genre]\n```\n\nRetrieve genre information from the DMM API based on floor ID.\n\nExample:\n\n```python\ngenres = client.get_genres(\n floor_id=43,\n initial=\"\u304d\",\n hits=10\n)\n```\n\nReference: `docs/development.md`\n\n#### get_makers\n\n```python\nget_makers(floor_id: int, **kwargs: Unpack[MakerSearchParams]) -> List[Maker]\n```\n\nRetrieve maker information from the DMM API based on floor ID.\n\nExample:\n\n```python\nmakers = client.get_makers(\n floor_id=43,\n initial=\"\u3042\",\n hits=10\n)\n```\n\nReference: `docs/makers.md`\n\n#### get_series\n\n```python\nget_series(floor_id: int, **kwargs: Unpack[SeriesSearchParams]) -> List[Series]\n```\n\nRetrieve series information from the DMM API based on floor ID.\n\nExample:\n\n```python\nseries = client.get_series(\n floor_id=27,\n initial=\"\u304a\",\n hits=10\n)\n```\n\nReference: `docs/development.md`\n\n#### get_authors\n\n```python\nget_authors(floor_id: int, **kwargs: Unpack[AuthorSearchParams]) -> List[Author]\n```\n\nRetrieve author information from the DMM API based on floor ID.\n\nExample:\n\n```python\nauthors = client.get_authors(\n floor_id=27,\n initial=\"\u3046\",\n hits=10\n)\n```\n\nReference: `docs/development.md`\n\n### Data Models\n\n#### Product\n\nThe `Product` dataclass represents detailed product information from the DMM API.\n\n**Key Attributes:**\n\n- `content_id` (str): Content ID for the product\n- `product_id` (str): Product ID (e.g., \"ABP-477\", \"MIRD-127\")\n- `title` (str): Product title in Japanese\n- `volume` (str): Volume or episode information\n- `URL` (str): Product detail page URL with affiliate tracking\n- `affiliate_URL` (str): Affiliate link URL\n- `imageURL` (ProductImageURL): Product images in multiple sizes\n- `prices` (ProductPrices): Pricing information\n- `date` (str): Release date in YYYY-MM-DD format\n- `iteminfo` (ProductItemInfo): Detailed product metadata (genres, series, maker, etc.)\n\n**Usage Example:**\n\n```python\nproducts = client.get_products(site=\"FANZA\", service=\"digital\", floor=\"videoa\", keyword=\"AIKA\", hits=5)\nfor product in products:\n print(f\"Title: {product.title}\")\n print(f\"Product ID: {product.product_id}\")\n print(f\"Price: {product.prices.price if product.prices else 'N/A'}\")\n```\n\nReference: `docs/products.md`\n\n#### Floor\n\nThe `Floor`, `Service`, and `Site` dataclasses represent the hierarchical structure of DMM's content organization.\n\n**Site** - Top-level organization:\n\n- `name` (str): Site name (e.g., \"DMM.com\uff08\u4e00\u822c\uff09\", \"FANZA\uff08\u30a2\u30c0\u30eb\u30c8\uff09\")\n- `code` (str): Site code (e.g., \"DMM.com\", \"FANZA\")\n- `services` (List[Service]): List of services available on this site\n\n**Service** - Mid-level organization:\n\n- `name` (str): Service name (e.g., \"\u52d5\u753b\", \"\u901a\u8ca9\")\n- `code` (str): Service code (e.g., \"digital\", \"mono\")\n- `floors` (List[Floor]): List of floors within this service\n\n**Floor** - Specific content category:\n\n- `id` (str): Floor ID (e.g., \"6\", \"43\")\n- `name` (str): Floor name (e.g., \"\u6620\u753b\u30fb\u30c9\u30e9\u30de\", \"\u30d3\u30c7\u30aa\")\n- `code` (str): Floor code (e.g., \"cinema\", \"videoa\")\n\n**Usage Example:**\n\n```python\nfloors = client.get_floors()\nfor site in floors:\n print(f\"Site: {site.name}\")\n for service in site.services:\n print(f\" Service: {service.name}\")\n for floor in service.floors:\n print(f\" Floor: {floor.name} (ID: {floor.id})\")\n```\n\nReference: `docs/development.md`\n\n#### Actress\n\nThe `Actress` dataclass represents actress information from the DMM Actress Search API.\n\n**Key Attributes:**\n\n- `id` (int): Actress ID\n- `name` (str): Actress name in Japanese\n- `ruby` (Optional[str]): Name phonetic reading\n- `bust` (Optional[int]): Bust measurement in cm\n- `cup` (Optional[str]): Cup size (e.g., \"H\", \"B\", \"C\")\n- `waist` (Optional[int]): Waist measurement in cm\n- `hip` (Optional[int]): Hip measurement in cm\n- `height` (Optional[int]): Height in cm\n- `birthday` (Optional[str]): Birthday in YYYY-MM-DD format\n- `blood_type` (Optional[str]): Blood type\n- `hobby` (Optional[str]): Hobbies and interests\n- `prefectures` (Optional[str]): Birthplace prefecture\n- `image_url` (Optional[ActressImageURL]): Image URLs (small, large)\n- `list_url` (Optional[ActressListURL]): Content list URLs (digital, monthly, mono)\n\n**Usage Example:**\n\n```python\nactresses = client.get_actresses(keyword=\"\u3042\u3055\u307f\", gte_bust=80, hits=10)\nfor actress in actresses:\n print(f\"Name: {actress.name} ({actress.ruby})\")\n print(f\"Measurements: B{actress.bust} W{actress.waist} H{actress.hip}\")\n print(f\"Height: {actress.height}cm\")\n```\n\nReference: `docs/actresses.md`\n\n#### Maker\n\nThe `Maker` dataclass represents maker (studio/publisher) information from the DMM Maker Search API.\n\n**Attributes:**\n\n- `maker_id` (str): Maker ID (e.g., \"1509\", \"45556\")\n- `name` (str): Maker name (e.g., \"\u30e0\u30fc\u30c7\u30a3\u30fc\u30ba\", \"\u30a2\u30bf\u30c3\u30ab\u30fc\u30ba\")\n- `ruby` (str): Maker name phonetic reading\n- `list_url` (str): List page URL with affiliate ID\n\n**Usage Example:**\n\n```python\nmakers = client.get_makers(floor_id=43, initial=\"\u3042\", hits=10)\nfor maker in makers:\n print(f\"Maker: {maker.name}\")\n print(f\"ID: {maker.maker_id}\")\n print(f\"Ruby: {maker.ruby}\")\n print(f\"URL: {maker.list_url}\")\n```\n\nReference: `docs/makers.md`\n\n#### Series\n\nThe `Series` dataclass represents series information from the DMM Series Search API.\n\n**Attributes:**\n\n- `series_id` (str): Series ID (e.g., \"62226\", \"105331\")\n- `name` (str): Series name (e.g., \"ARIA\", \"\u304a\u3042\u3044\u306b\u304f\u3055\u307e\u4e8c\u30ce\u5bae\u304f\u3093\")\n- `ruby` (str): Series name phonetic reading\n- `list_url` (str): List page URL with affiliate ID\n\n**Usage Example:**\n\n```python\nseries = client.get_series(floor_id=27, initial=\"\u304a\", hits=10)\nfor s in series:\n print(f\"Series: {s.name}\")\n print(f\"ID: {s.series_id}\")\n print(f\"Ruby: {s.ruby}\")\n```\n\nReference: `docs/development.md`\n\n#### Genre\n\nThe `Genre` dataclass represents genre/category information from the DMM Genre Search API.\n\n**Attributes:**\n\n- `genre_id` (str): Genre ID (e.g., \"2001\", \"73115\")\n- `name` (str): Genre name (e.g., \"\u5de8\u4e73\", \"\u30ad\u30e3\u30e9\u30af\u30bf\u30fc\")\n- `ruby` (str): Genre name phonetic reading\n- `list_url` (str): List page URL with affiliate ID\n\n**Usage Example:**\n\n```python\ngenres = client.get_genres(floor_id=43, initial=\"\u304d\", hits=10)\nfor genre in genres:\n print(f\"Genre: {genre.name}\")\n print(f\"ID: {genre.genre_id}\")\n print(f\"Ruby: {genre.ruby}\")\n```\n\nReference: `docs/development.md`\n\n#### Author\n\nThe `Author` dataclass represents author information from the DMM Author Search API.\n\n**Attributes:**\n\n- `author_id` (str): Author ID (e.g., \"21414\", \"182179\")\n- `name` (str): Author name (e.g., \"\u30f4\u30a3\u30af\u30c8\u30eb\u30fb\u30e6\u30b4\u30fc\", \"\u30a6\u30a3\u30af\u30bb\u30eb\")\n- `ruby` (str): Author name phonetic reading\n- `list_url` (str): List page URL with affiliate ID\n- `another_name` (str): Author alias/another name\n\n**Usage Example:**\n\n```python\nauthors = client.get_authors(floor_id=27, initial=\"\u3046\", hits=10)\nfor author in authors:\n print(f\"Author: {author.name}\")\n print(f\"ID: {author.author_id}\")\n print(f\"Ruby: {author.ruby}\")\n if author.another_name:\n print(f\"Also known as: {author.another_name}\")\n```\n\nReference: `docs/development.md`\n\n### Exception Handling\n\nThe library provides custom exceptions for better error handling:\n\n#### DMMError\n\nBase exception class for all py-dmm errors.\n\n**Attributes:**\n\n- `message` (str): The error message\n- `details` (Optional[Any]): Additional error details\n\n**Usage Example:**\n\n```python\nfrom py_dmmjp.exceptions import DMMError\n\ntry:\n # Your code here\n pass\nexcept DMMError as e:\n print(f\"Error: {e.message}\")\n if e.details:\n print(f\"Details: {e.details}\")\n```\n\n#### DMMAPIError\n\nException raised for API-related errors. Inherits from `DMMError`.\n\n**Attributes:**\n\n- `message` (str): The error message\n- `status_code` (Optional[int]): HTTP status code of the failed request\n- `response_data` (Optional[Any]): Raw response data from the API\n\n**Usage Example:**\n\n```python\nfrom py_dmmjp.exceptions import DMMAPIError\n\ntry:\n products = client.get_products(site=\"FANZA\", service=\"digital\", floor=\"videoa\")\nexcept DMMAPIError as e:\n print(f\"API Error: {e.message}\")\n print(f\"Status Code: {e.status_code}\")\n print(f\"Response: {e.response_data}\")\n```\n\n#### DMMAuthError\n\nException raised for authentication-related errors. Inherits from `DMMError`.\n\n**Attributes:**\n\n- `message` (str): The error message (default: \"Authentication failed\")\n\n**Usage Example:**\n\n```python\nfrom py_dmmjp import DMMClient\nfrom py_dmmjp.exceptions import DMMAuthError\n\ntry:\n client = DMMClient(api_key=\"invalid_key\", affiliate_id=\"invalid_id\")\n products = client.get_products(site=\"FANZA\")\nexcept DMMAuthError as e:\n print(f\"Authentication Error: {e.message}\")\n```\n\n## Development\n\n### Setup Development Environment\n\n1. Clone the repository:\n\n ```bash\n git clone https://github.com/richardnguyen99/py-dmmjp.git\n cd py-dmmjp\n ```\n\n2. Install development dependencies:\n\n ```bash\n pip install -r requirements-dev.txt\n ```\n\n3. Install pre-commit hooks:\n\n ```bash\n pre-commit install\n ```\n\n### Running Tests\n\n```bash\n# Run all tests\npytest\n\n# Run tests with coverage\npytest --cov=py_dmm\n\n# Run specific test file\npytest tests/test_series_dvd.py\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.\n\nPlease make sure to:\n\n1. Update tests as appropriate\n2. Follow the existing code style (black + isort)\n3. Add type hints to new code\n4. Update documentation for new features\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for a detailed history of changes.\n\n## Support\n\n- \ud83d\udcd6 [Documentation](https://py-dmmjp.readthedocs.io/)\n- \ud83d\udc1b [Issue Tracker](https://github.com/richardnguyen99/py-dmmjp/issues)\n- \ud83d\udcac [Discussions](https://github.com/richardnguyen99/py-dmmjp/discussions)\n",
"bugtrack_url": null,
"license": "MIT License\n \n Copyright (c) 2025 Richard Nguyen\n \n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n \n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n \n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n ",
"summary": "A Python client library for the DMM API",
"version": "0.0.11",
"project_urls": {
"Documentation": "https://py-dmm.readthedocs.io/",
"Homepage": "https://github.com/richardnguyen99/py-dmm",
"Repository": "https://github.com/richardnguyen99/py-dmm.git"
},
"split_keywords": [
"dmm",
" api",
" client",
" digital",
" media",
" affiliate"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "d2c018436f92f3ed8cd48dd9600bbc545847812919f91b57ee4e3c140300a40a",
"md5": "5055a18728687213eaac07cd21fe59d0",
"sha256": "01858a543eecac9aaa2509551829429baee18ef5cc2eaa329e475540be4a581d"
},
"downloads": -1,
"filename": "py_dmmjp-0.0.11-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5055a18728687213eaac07cd21fe59d0",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 30692,
"upload_time": "2025-10-21T05:04:44",
"upload_time_iso_8601": "2025-10-21T05:04:44.146072Z",
"url": "https://files.pythonhosted.org/packages/d2/c0/18436f92f3ed8cd48dd9600bbc545847812919f91b57ee4e3c140300a40a/py_dmmjp-0.0.11-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "6bff010edb22062ba00e34d1b999964b3cf53938cb0960098414c3fa7cf8ad57",
"md5": "43d82684856bb081e83456cf45830c1c",
"sha256": "c314f046642340f0f9b6bf62370d7295380bbd588ed62b1c7ccced7f693b913a"
},
"downloads": -1,
"filename": "py_dmmjp-0.0.11.tar.gz",
"has_sig": false,
"md5_digest": "43d82684856bb081e83456cf45830c1c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 118820,
"upload_time": "2025-10-21T05:04:45",
"upload_time_iso_8601": "2025-10-21T05:04:45.348194Z",
"url": "https://files.pythonhosted.org/packages/6b/ff/010edb22062ba00e34d1b999964b3cf53938cb0960098414c3fa7cf8ad57/py_dmmjp-0.0.11.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-21 05:04:45",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "richardnguyen99",
"github_project": "py-dmm",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "requests",
"specs": [
[
">=",
"2.25.0"
]
]
},
{
"name": "typing-extensions",
"specs": [
[
">=",
"4.0.0"
]
]
}
],
"lcname": "py-dmmjp"
}