beachdayapi 0.1.0__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.
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.4
2
+ Name: beachdayapi
3
+ Version: 0.1.0
4
+ Summary: Python client for the Beach Day API — real-time beach and surf conditions
5
+ Author-email: Beach Day API <hello@beachdayapi.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://beachdayapi.com
8
+ Project-URL: Documentation, https://beachdayapi.com/docs
9
+ Project-URL: Repository, https://github.com/rv888/beachdayapi
10
+ Project-URL: Issues, https://github.com/rv888/beachdayapi/issues
11
+ Keywords: beach,surf,water-quality,weather,api
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
22
+ Classifier: Topic :: Internet :: WWW/HTTP
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/markdown
25
+
26
+ # Beach Day API — Python Client
27
+
28
+ [![PyPI version](https://img.shields.io/pypi/v/beachdayapi.svg)](https://pypi.org/project/beachdayapi/)
29
+ [![Python](https://img.shields.io/pypi/pyversions/beachdayapi.svg)](https://pypi.org/project/beachdayapi/)
30
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
31
+
32
+ Python client for the [Beach Day API](https://beachdayapi.com) — water quality, weather, tides, ocean conditions, beach rules, amenities, and composite scoring in a single call. Covers 1,900+ beaches across the US and Australia.
33
+
34
+ ```bash
35
+ pip install beachdayapi
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ```python
41
+ from beachdayapi import BeachDayAPI
42
+
43
+ client = BeachDayAPI("bda_your_api_key")
44
+
45
+ # Search beaches in California
46
+ beaches = client.beaches.list(state="CA")
47
+ for b in beaches["data"]:
48
+ print(b["name"], b["state"])
49
+
50
+ # Get full detail for a beach
51
+ beach = client.beaches.get(372)
52
+ print(beach["data"]["name"], beach["data"]["beach_day_score"])
53
+
54
+ # Get current conditions
55
+ conditions = client.beaches.conditions(372)
56
+ print(conditions["data"]["water_quality_grade"])
57
+
58
+ # Get top-scored beaches
59
+ scored = client.beaches.scored(min_score=70, limit=10)
60
+ for b in scored["data"]:
61
+ print(f"{b['name']}: {b['beach_day_score']}")
62
+
63
+ # Health check (no API key needed)
64
+ health = client.health()
65
+ print(health)
66
+ ```
67
+
68
+ ## API Key
69
+
70
+ Sign up at [beachdayapi.com](https://beachdayapi.com) to get your free API key (50 free credits, no credit card). Your key starts with `bda_`.
71
+
72
+ You can also set the `BEACHDAY_API_KEY` environment variable:
73
+
74
+ ```python
75
+ import os
76
+ from beachdayapi import BeachDayAPI
77
+
78
+ client = BeachDayAPI(os.environ["BEACHDAY_API_KEY"])
79
+ ```
80
+
81
+ ## Endpoints
82
+
83
+ | Method | Endpoint | Cost | Description |
84
+ |---|---|---|---|
85
+ | `client.health()` | `GET /v1/health` | Free | API health check |
86
+ | `client.beaches.list()` | `GET /v1/beaches` | 1 credit | Search beaches |
87
+ | `client.beaches.get(id)` | `GET /v1/beaches/{id}` | 5 credits | Beach detail |
88
+ | `client.beaches.conditions(id)` | `GET /v1/beaches/{id}/conditions` | 3 credits | Current conditions |
89
+ | `client.beaches.scored()` | `GET /v1/beaches/scored` | 10 credits | Scored beaches |
90
+
91
+ ## Error Handling
92
+
93
+ ```python
94
+ from beachdayapi import (
95
+ BeachDayAPI,
96
+ AuthenticationError,
97
+ InsufficientCreditsError,
98
+ NotFoundError,
99
+ RateLimitError,
100
+ ServerError,
101
+ )
102
+
103
+ client = BeachDayAPI("bda_invalid_key")
104
+
105
+ try:
106
+ client.beaches.list(state="CA")
107
+ except AuthenticationError:
108
+ print("Check your API key")
109
+ except InsufficientCreditsError:
110
+ print("Buy more credits at beachdayapi.com/credits/pricing/")
111
+ except RateLimitError:
112
+ print("Slow down")
113
+ ```
114
+
115
+ ## Requirements
116
+
117
+ - Python 3.9+
118
+ - Zero dependencies (stdlib only)
119
+
120
+ ## License
121
+
122
+ MIT — see the main [Beach Day API repository](https://github.com/rv888/beachdayapi).
@@ -0,0 +1,97 @@
1
+ # Beach Day API — Python Client
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/beachdayapi.svg)](https://pypi.org/project/beachdayapi/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/beachdayapi.svg)](https://pypi.org/project/beachdayapi/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ Python client for the [Beach Day API](https://beachdayapi.com) — water quality, weather, tides, ocean conditions, beach rules, amenities, and composite scoring in a single call. Covers 1,900+ beaches across the US and Australia.
8
+
9
+ ```bash
10
+ pip install beachdayapi
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```python
16
+ from beachdayapi import BeachDayAPI
17
+
18
+ client = BeachDayAPI("bda_your_api_key")
19
+
20
+ # Search beaches in California
21
+ beaches = client.beaches.list(state="CA")
22
+ for b in beaches["data"]:
23
+ print(b["name"], b["state"])
24
+
25
+ # Get full detail for a beach
26
+ beach = client.beaches.get(372)
27
+ print(beach["data"]["name"], beach["data"]["beach_day_score"])
28
+
29
+ # Get current conditions
30
+ conditions = client.beaches.conditions(372)
31
+ print(conditions["data"]["water_quality_grade"])
32
+
33
+ # Get top-scored beaches
34
+ scored = client.beaches.scored(min_score=70, limit=10)
35
+ for b in scored["data"]:
36
+ print(f"{b['name']}: {b['beach_day_score']}")
37
+
38
+ # Health check (no API key needed)
39
+ health = client.health()
40
+ print(health)
41
+ ```
42
+
43
+ ## API Key
44
+
45
+ Sign up at [beachdayapi.com](https://beachdayapi.com) to get your free API key (50 free credits, no credit card). Your key starts with `bda_`.
46
+
47
+ You can also set the `BEACHDAY_API_KEY` environment variable:
48
+
49
+ ```python
50
+ import os
51
+ from beachdayapi import BeachDayAPI
52
+
53
+ client = BeachDayAPI(os.environ["BEACHDAY_API_KEY"])
54
+ ```
55
+
56
+ ## Endpoints
57
+
58
+ | Method | Endpoint | Cost | Description |
59
+ |---|---|---|---|
60
+ | `client.health()` | `GET /v1/health` | Free | API health check |
61
+ | `client.beaches.list()` | `GET /v1/beaches` | 1 credit | Search beaches |
62
+ | `client.beaches.get(id)` | `GET /v1/beaches/{id}` | 5 credits | Beach detail |
63
+ | `client.beaches.conditions(id)` | `GET /v1/beaches/{id}/conditions` | 3 credits | Current conditions |
64
+ | `client.beaches.scored()` | `GET /v1/beaches/scored` | 10 credits | Scored beaches |
65
+
66
+ ## Error Handling
67
+
68
+ ```python
69
+ from beachdayapi import (
70
+ BeachDayAPI,
71
+ AuthenticationError,
72
+ InsufficientCreditsError,
73
+ NotFoundError,
74
+ RateLimitError,
75
+ ServerError,
76
+ )
77
+
78
+ client = BeachDayAPI("bda_invalid_key")
79
+
80
+ try:
81
+ client.beaches.list(state="CA")
82
+ except AuthenticationError:
83
+ print("Check your API key")
84
+ except InsufficientCreditsError:
85
+ print("Buy more credits at beachdayapi.com/credits/pricing/")
86
+ except RateLimitError:
87
+ print("Slow down")
88
+ ```
89
+
90
+ ## Requirements
91
+
92
+ - Python 3.9+
93
+ - Zero dependencies (stdlib only)
94
+
95
+ ## License
96
+
97
+ MIT — see the main [Beach Day API repository](https://github.com/rv888/beachdayapi).
@@ -0,0 +1,29 @@
1
+ """Beach Day API Python Client
2
+
3
+ A lightweight Python client for the Beach Day API.
4
+
5
+ pip install beachdayapi
6
+
7
+ Usage:
8
+ from beachdayapi import BeachDayAPI
9
+
10
+ client = BeachDayAPI("bda_your_api_key")
11
+
12
+ # Search beaches
13
+ beaches = client.beaches.list(state="CA")
14
+
15
+ # Get beach detail
16
+ beach = client.beaches.get(372)
17
+
18
+ # Get scored beaches
19
+ scored = client.beaches.scored(min_score=70)
20
+
21
+ # Health check (no auth)
22
+ health = client.health()
23
+ """
24
+
25
+ from .client import BeachDayAPI
26
+ from .exceptions import BeachDayAPIError, AuthenticationError, InsufficientCreditsError
27
+
28
+ __all__ = ["BeachDayAPI", "BeachDayAPIError", "AuthenticationError", "InsufficientCreditsError"]
29
+ __version__ = "0.1.0"
@@ -0,0 +1,157 @@
1
+ import urllib.request
2
+ import urllib.error
3
+ import urllib.parse
4
+ import json
5
+ from typing import Optional, Dict, Any, List
6
+ from .exceptions import (
7
+ AuthenticationError,
8
+ InsufficientCreditsError,
9
+ NotFoundError,
10
+ RateLimitError,
11
+ ServerError,
12
+ BeachDayAPIError,
13
+ )
14
+
15
+
16
+ class BeachDayAPI:
17
+ """Client for the Beach Day API.
18
+
19
+ Args:
20
+ api_key: Your Beach Day API key (starts with 'bda_').
21
+ base_url: Override the API base URL. Defaults to production.
22
+ timeout: Request timeout in seconds. Default 30.
23
+ """
24
+
25
+ BASE_URL = "https://beachdayapi.com/v1"
26
+
27
+ def __init__(
28
+ self,
29
+ api_key: Optional[str] = None,
30
+ base_url: Optional[str] = None,
31
+ timeout: int = 30,
32
+ ):
33
+ self.api_key = api_key
34
+ self.base_url = base_url or self.BASE_URL
35
+ self.timeout = timeout
36
+ self.beaches = BeachEndpoints(self)
37
+ self.health = lambda: self._get("/health", auth_required=False)
38
+
39
+ def _auth_headers(self) -> Dict[str, str]:
40
+ return {"Authorization": f"Bearer {self.api_key}"}
41
+
42
+ def _request(
43
+ self,
44
+ method: str,
45
+ path: str,
46
+ params: Optional[Dict[str, Any]] = None,
47
+ auth_required: bool = True,
48
+ ) -> Dict[str, Any]:
49
+ url = f"{self.base_url}{path}"
50
+ headers = {"Accept": "application/json", "User-Agent": "beachdayapi-python/0.1.0"}
51
+ if auth_required:
52
+ if not self.api_key:
53
+ raise AuthenticationError(
54
+ "API key required. Pass api_key='bda_...' to BeachDayAPI(), "
55
+ "or set BEACHDAY_API_KEY environment variable."
56
+ )
57
+ headers.update(self._auth_headers())
58
+
59
+ if params:
60
+ filtered = {k: v for k, v in params.items() if v is not None}
61
+ if filtered:
62
+ url = f"{url}?{urllib.parse.urlencode(filtered)}"
63
+
64
+ req = urllib.request.Request(url, method=method, headers=headers)
65
+
66
+ try:
67
+ with urllib.request.urlopen(req, timeout=self.timeout) as resp:
68
+ return json.loads(resp.read().decode("utf-8"))
69
+ except urllib.error.HTTPError as e:
70
+ body = {}
71
+ try:
72
+ body = json.loads(e.read().decode("utf-8"))
73
+ except Exception:
74
+ pass
75
+ self._raise_error(e.code, body)
76
+ return {} # unreachable, satisfies type checker
77
+ except urllib.error.URLError as e:
78
+ raise BeachDayAPIError(f"Connection error: {e.reason}") from e
79
+
80
+ def _get(
81
+ self, path: str, params=None, auth_required=True
82
+ ) -> Dict[str, Any]:
83
+ return self._request("GET", path, params, auth_required)
84
+
85
+ @staticmethod
86
+ def _raise_error(status: int, body: dict):
87
+ detail = body.get("detail") or body.get("message", "")
88
+ if status == 401:
89
+ raise AuthenticationError(detail or "Invalid or missing API key.")
90
+ if status == 402:
91
+ required = body.get("required", "?")
92
+ balance = body.get("balance", "?")
93
+ msg = f"Insufficient credits. Need {required}, have {balance}."
94
+ raise InsufficientCreditsError(msg)
95
+ if status == 404:
96
+ raise NotFoundError(detail or "Resource not found.")
97
+ if status == 429:
98
+ raise RateLimitError(detail or "Too many requests.")
99
+ if 500 <= status < 600:
100
+ raise ServerError(detail or f"Server error (HTTP {status}).")
101
+ raise BeachDayAPIError(f"HTTP {status}: {detail or 'Unknown error'}")
102
+
103
+
104
+ class BeachEndpoints:
105
+ """Access beach-related endpoints."""
106
+
107
+ def __init__(self, client: BeachDayAPI):
108
+ self._client = client
109
+
110
+ def list(
111
+ self,
112
+ state: Optional[str] = None,
113
+ search: Optional[str] = None,
114
+ limit: Optional[int] = None,
115
+ offset: Optional[int] = None,
116
+ ) -> Dict[str, Any]:
117
+ """List beaches with optional filters.
118
+
119
+ Args:
120
+ state: Two-letter US state code or 'AU-NSW'/'AU-VIC'.
121
+ search: Search term for beach name.
122
+ limit: Max results per page.
123
+ offset: Pagination offset.
124
+ """
125
+ return self._client._get("/beaches", {
126
+ "state": state,
127
+ "search": search,
128
+ "limit": limit,
129
+ "offset": offset,
130
+ })
131
+
132
+ def get(self, beach_id: int) -> Dict[str, Any]:
133
+ """Get full detail for a single beach."""
134
+ return self._client._get(f"/beaches/{beach_id}")
135
+
136
+ def conditions(self, beach_id: int) -> Dict[str, Any]:
137
+ """Get current conditions for a beach."""
138
+ return self._client._get(f"/beaches/{beach_id}/conditions")
139
+
140
+ def scored(
141
+ self,
142
+ state: Optional[str] = None,
143
+ min_score: Optional[int] = None,
144
+ limit: Optional[int] = None,
145
+ ) -> Dict[str, Any]:
146
+ """Get beaches with composite Beach Day Scores.
147
+
148
+ Args:
149
+ state: Filter by state code.
150
+ min_score: Minimum score threshold (0-100).
151
+ limit: Max results.
152
+ """
153
+ return self._client._get("/beaches/scored", {
154
+ "state": state,
155
+ "min_score": min_score,
156
+ "limit": limit,
157
+ })
@@ -0,0 +1,28 @@
1
+ class BeachDayAPIError(Exception):
2
+ """Base exception for Beach Day API errors."""
3
+ pass
4
+
5
+
6
+ class AuthenticationError(BeachDayAPIError):
7
+ """Invalid or missing API key (HTTP 401)."""
8
+ pass
9
+
10
+
11
+ class InsufficientCreditsError(BeachDayAPIError):
12
+ """Not enough credits for the request (HTTP 402)."""
13
+ pass
14
+
15
+
16
+ class NotFoundError(BeachDayAPIError):
17
+ """Resource not found (HTTP 404)."""
18
+ pass
19
+
20
+
21
+ class RateLimitError(BeachDayAPIError):
22
+ """Rate limit exceeded (HTTP 429)."""
23
+ pass
24
+
25
+
26
+ class ServerError(BeachDayAPIError):
27
+ """Server-side error (HTTP 5xx)."""
28
+ pass
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.4
2
+ Name: beachdayapi
3
+ Version: 0.1.0
4
+ Summary: Python client for the Beach Day API — real-time beach and surf conditions
5
+ Author-email: Beach Day API <hello@beachdayapi.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://beachdayapi.com
8
+ Project-URL: Documentation, https://beachdayapi.com/docs
9
+ Project-URL: Repository, https://github.com/rv888/beachdayapi
10
+ Project-URL: Issues, https://github.com/rv888/beachdayapi/issues
11
+ Keywords: beach,surf,water-quality,weather,api
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
22
+ Classifier: Topic :: Internet :: WWW/HTTP
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/markdown
25
+
26
+ # Beach Day API — Python Client
27
+
28
+ [![PyPI version](https://img.shields.io/pypi/v/beachdayapi.svg)](https://pypi.org/project/beachdayapi/)
29
+ [![Python](https://img.shields.io/pypi/pyversions/beachdayapi.svg)](https://pypi.org/project/beachdayapi/)
30
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
31
+
32
+ Python client for the [Beach Day API](https://beachdayapi.com) — water quality, weather, tides, ocean conditions, beach rules, amenities, and composite scoring in a single call. Covers 1,900+ beaches across the US and Australia.
33
+
34
+ ```bash
35
+ pip install beachdayapi
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ```python
41
+ from beachdayapi import BeachDayAPI
42
+
43
+ client = BeachDayAPI("bda_your_api_key")
44
+
45
+ # Search beaches in California
46
+ beaches = client.beaches.list(state="CA")
47
+ for b in beaches["data"]:
48
+ print(b["name"], b["state"])
49
+
50
+ # Get full detail for a beach
51
+ beach = client.beaches.get(372)
52
+ print(beach["data"]["name"], beach["data"]["beach_day_score"])
53
+
54
+ # Get current conditions
55
+ conditions = client.beaches.conditions(372)
56
+ print(conditions["data"]["water_quality_grade"])
57
+
58
+ # Get top-scored beaches
59
+ scored = client.beaches.scored(min_score=70, limit=10)
60
+ for b in scored["data"]:
61
+ print(f"{b['name']}: {b['beach_day_score']}")
62
+
63
+ # Health check (no API key needed)
64
+ health = client.health()
65
+ print(health)
66
+ ```
67
+
68
+ ## API Key
69
+
70
+ Sign up at [beachdayapi.com](https://beachdayapi.com) to get your free API key (50 free credits, no credit card). Your key starts with `bda_`.
71
+
72
+ You can also set the `BEACHDAY_API_KEY` environment variable:
73
+
74
+ ```python
75
+ import os
76
+ from beachdayapi import BeachDayAPI
77
+
78
+ client = BeachDayAPI(os.environ["BEACHDAY_API_KEY"])
79
+ ```
80
+
81
+ ## Endpoints
82
+
83
+ | Method | Endpoint | Cost | Description |
84
+ |---|---|---|---|
85
+ | `client.health()` | `GET /v1/health` | Free | API health check |
86
+ | `client.beaches.list()` | `GET /v1/beaches` | 1 credit | Search beaches |
87
+ | `client.beaches.get(id)` | `GET /v1/beaches/{id}` | 5 credits | Beach detail |
88
+ | `client.beaches.conditions(id)` | `GET /v1/beaches/{id}/conditions` | 3 credits | Current conditions |
89
+ | `client.beaches.scored()` | `GET /v1/beaches/scored` | 10 credits | Scored beaches |
90
+
91
+ ## Error Handling
92
+
93
+ ```python
94
+ from beachdayapi import (
95
+ BeachDayAPI,
96
+ AuthenticationError,
97
+ InsufficientCreditsError,
98
+ NotFoundError,
99
+ RateLimitError,
100
+ ServerError,
101
+ )
102
+
103
+ client = BeachDayAPI("bda_invalid_key")
104
+
105
+ try:
106
+ client.beaches.list(state="CA")
107
+ except AuthenticationError:
108
+ print("Check your API key")
109
+ except InsufficientCreditsError:
110
+ print("Buy more credits at beachdayapi.com/credits/pricing/")
111
+ except RateLimitError:
112
+ print("Slow down")
113
+ ```
114
+
115
+ ## Requirements
116
+
117
+ - Python 3.9+
118
+ - Zero dependencies (stdlib only)
119
+
120
+ ## License
121
+
122
+ MIT — see the main [Beach Day API repository](https://github.com/rv888/beachdayapi).
@@ -0,0 +1,9 @@
1
+ README.md
2
+ pyproject.toml
3
+ beachdayapi/__init__.py
4
+ beachdayapi/client.py
5
+ beachdayapi/exceptions.py
6
+ beachdayapi.egg-info/PKG-INFO
7
+ beachdayapi.egg-info/SOURCES.txt
8
+ beachdayapi.egg-info/dependency_links.txt
9
+ beachdayapi.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ beachdayapi
@@ -0,0 +1,36 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "beachdayapi"
7
+ version = "0.1.0"
8
+ description = "Python client for the Beach Day API — real-time beach and surf conditions"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ authors = [{name = "Beach Day API", email = "hello@beachdayapi.com"}]
12
+ keywords = ["beach", "surf", "water-quality", "weather", "api"]
13
+ classifiers = [
14
+ "Development Status :: 4 - Beta",
15
+ "Intended Audience :: Developers",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3.9",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Topic :: Scientific/Engineering :: Atmospheric Science",
24
+ "Topic :: Internet :: WWW/HTTP",
25
+ ]
26
+ requires-python = ">=3.9"
27
+ dependencies = []
28
+
29
+ [project.urls]
30
+ Homepage = "https://beachdayapi.com"
31
+ Documentation = "https://beachdayapi.com/docs"
32
+ Repository = "https://github.com/rv888/beachdayapi"
33
+ Issues = "https://github.com/rv888/beachdayapi/issues"
34
+
35
+ [tool.setuptools]
36
+ packages = ["beachdayapi"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+