cronradar 0.0.1__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.

Potentially problematic release.


This version of cronradar might be problematic. Click here for more details.

@@ -0,0 +1,41 @@
1
+ CronRadar SDK License
2
+
3
+ Copyright (c) 2025 CronRadar. All rights reserved.
4
+
5
+ ## Permitted Use
6
+
7
+ You may use this software solely in connection with the CronRadar monitoring
8
+ service available at cronradar.com. You may view, study, and modify the source
9
+ code for the purpose of fixing bugs or improving functionality.
10
+
11
+ ## Contributions
12
+
13
+ If you modify this software to fix bugs or add improvements, you may submit
14
+ those modifications back to CronRadar via pull request. By submitting, you
15
+ grant CronRadar a perpetual, worldwide, non-exclusive, royalty-free license
16
+ to use, modify, and distribute your contributions under any terms.
17
+
18
+ ## Restrictions
19
+
20
+ You may NOT:
21
+ - Use this software with any service other than CronRadar
22
+ - Fork or use this software for your own projects or products
23
+ - Redistribute this software (use official package managers only)
24
+ - Create derivative works for purposes other than contributing back to CronRadar
25
+ - Remove or modify any license, copyright, or attribution notices
26
+ - Use this software to create a competing monitoring service
27
+
28
+ ## Termination
29
+
30
+ Your license terminates immediately if you violate any restriction. Upon
31
+ termination, you must stop using the software.
32
+
33
+ ## Disclaimer
34
+
35
+ THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36
+ IMPLIED. IN NO EVENT SHALL CRONRADAR BE LIABLE FOR ANY DAMAGES ARISING FROM
37
+ THE USE OF THIS SOFTWARE.
38
+
39
+ ## Questions
40
+
41
+ For licensing questions: support@cronradar.com
@@ -0,0 +1,76 @@
1
+ Metadata-Version: 2.4
2
+ Name: cronradar
3
+ Version: 0.0.1
4
+ Summary: Dead-simple cron job monitoring with auto-registration. Two functions: ping() and sync_monitor(). Self-healing monitors.
5
+ Home-page: https://github.com/cronradar/cronradar-python
6
+ Author: Administrator
7
+ Author-email: contact@cronradar.com
8
+ License: Proprietary
9
+ Project-URL: Documentation, https://cronradar.com/docs
10
+ Project-URL: Source, https://github.com/cronradar/cronradar-python
11
+ Project-URL: Tracker, https://github.com/cronradar/cronradar-python/issues
12
+ Keywords: cron monitoring scheduler job task ping sync auto-register
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: Other/Proprietary License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Topic :: System :: Monitoring
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Dynamic: author
29
+ Dynamic: author-email
30
+ Dynamic: classifier
31
+ Dynamic: description
32
+ Dynamic: description-content-type
33
+ Dynamic: home-page
34
+ Dynamic: keywords
35
+ Dynamic: license
36
+ Dynamic: license-file
37
+ Dynamic: project-url
38
+ Dynamic: requires-python
39
+ Dynamic: summary
40
+
41
+ # CronRadar Python SDK
42
+
43
+ Monitor cron jobs with one function call.
44
+
45
+ ## Installation
46
+
47
+ ```bash
48
+ pip install cronradar
49
+ ```
50
+
51
+ ## Usage
52
+
53
+ ```python
54
+ import cronradar
55
+
56
+ # After your cron job completes successfully
57
+ cronradar.ping('daily-backup')
58
+
59
+ # With self-healing (auto-register if monitor doesn't exist)
60
+ cronradar.ping('daily-backup', schedule='0 2 * * *', grace_period=300)
61
+ ```
62
+
63
+ ## Configuration
64
+
65
+ Set environment variable:
66
+ - `CRONRADAR_API_KEY`: Your API key from cronradar.com
67
+ - `CRONRADAR_BASE_URL`: Base URL override (optional, default: `https://cronradar.com`)
68
+ - `CRONRADAR_METHOD`: HTTP method for ping (optional, default: `GET`)
69
+
70
+ ## Documentation
71
+
72
+ See [cronradar.com/docs](https://cronradar.com/docs) for full documentation.
73
+
74
+ ## License
75
+
76
+ MIT
@@ -0,0 +1,36 @@
1
+ # CronRadar Python SDK
2
+
3
+ Monitor cron jobs with one function call.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install cronradar
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```python
14
+ import cronradar
15
+
16
+ # After your cron job completes successfully
17
+ cronradar.ping('daily-backup')
18
+
19
+ # With self-healing (auto-register if monitor doesn't exist)
20
+ cronradar.ping('daily-backup', schedule='0 2 * * *', grace_period=300)
21
+ ```
22
+
23
+ ## Configuration
24
+
25
+ Set environment variable:
26
+ - `CRONRADAR_API_KEY`: Your API key from cronradar.com
27
+ - `CRONRADAR_BASE_URL`: Base URL override (optional, default: `https://cronradar.com`)
28
+ - `CRONRADAR_METHOD`: HTTP method for ping (optional, default: `GET`)
29
+
30
+ ## Documentation
31
+
32
+ See [cronradar.com/docs](https://cronradar.com/docs) for full documentation.
33
+
34
+ ## License
35
+
36
+ MIT
@@ -0,0 +1,221 @@
1
+ """
2
+ CronRadar Python SDK
3
+
4
+ Dead-simple cron job monitoring with auto-registration support.
5
+ Two main functions: ping() for execution confirmation, sync_monitor() for registration.
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ import base64
11
+ import json
12
+ import traceback
13
+ from typing import Optional
14
+ from urllib.request import Request, urlopen
15
+ from urllib.error import URLError, HTTPError
16
+
17
+
18
+ __version__ = "0.0.1"
19
+
20
+
21
+ def ping(monitor_key: str, schedule: Optional[str] = None) -> None:
22
+ """
23
+ Ping CronRadar to indicate your job has run successfully.
24
+ Optionally provide schedule for self-healing (auto-registration on 404).
25
+
26
+ Args:
27
+ monitor_key: The monitor key identifying your job
28
+ schedule: Optional cron schedule for auto-registration if monitor doesn't exist
29
+
30
+ Returns:
31
+ None
32
+
33
+ Raises:
34
+ Never throws - all errors are suppressed to protect job execution
35
+ """
36
+ try:
37
+ api_key = os.environ.get('CRONRADAR_API_KEY', '')
38
+ if not api_key:
39
+ print(f"[CronRadar] Warning: CRONRADAR_API_KEY environment variable not set. Monitor '{monitor_key}' will not be tracked.", file=sys.stderr)
40
+ return
41
+
42
+ # Try to ping
43
+ status_code = _send_ping_internal(monitor_key, api_key)
44
+
45
+ # Self-healing: if monitor doesn't exist and schedule provided, create it
46
+ if status_code == 404 and schedule:
47
+ print(f"[CronRadar] Monitor '{monitor_key}' not found. Auto-registering with schedule '{schedule}'...", file=sys.stderr)
48
+
49
+ source = _detect_source()
50
+ sync_monitor(monitor_key, schedule, source=source)
51
+
52
+ # Retry ping
53
+ _send_ping_internal(monitor_key, api_key)
54
+ except Exception as e:
55
+ # Never throw - protect user's job execution
56
+ # Optionally log for debugging
57
+ print(f"[CronRadar] Error during ping: {e}", file=sys.stderr)
58
+
59
+
60
+ def sync_monitor(
61
+ monitor_key: str,
62
+ schedule: str,
63
+ source: Optional[str] = None,
64
+ name: Optional[str] = None
65
+ ) -> None:
66
+ """
67
+ Register a monitor with CronRadar, setting up expectations for when it should run.
68
+ Used by extensions to sync discovered jobs.
69
+
70
+ Args:
71
+ monitor_key: The unique identifier for this monitor
72
+ schedule: Cron expression defining when the job runs
73
+ source: Source framework (e.g., "celery", "airflow"). Auto-detected if None.
74
+ name: Human-readable name. Generated from key if None.
75
+
76
+ Returns:
77
+ None
78
+
79
+ Raises:
80
+ Never throws - all errors are suppressed to protect job execution
81
+ """
82
+ try:
83
+ api_key = os.environ.get('CRONRADAR_API_KEY', '')
84
+ if not api_key:
85
+ print(f"[CronRadar] Warning: CRONRADAR_API_KEY environment variable not set. Monitor '{monitor_key}' will not be synced.", file=sys.stderr)
86
+ return
87
+
88
+ source = source or _detect_source()
89
+ name = name or _generate_readable_name(monitor_key)
90
+
91
+ sync_request = {
92
+ 'source': source,
93
+ 'monitors': [{
94
+ 'key': monitor_key,
95
+ 'name': name,
96
+ 'schedule': schedule,
97
+ 'gracePeriod': 60
98
+ }]
99
+ }
100
+
101
+ url = 'https://api.cronradar.com/api/sync'
102
+
103
+ # Prepare request
104
+ data = json.dumps(sync_request).encode('utf-8')
105
+ auth_string = f"{api_key}:".encode('utf-8')
106
+ auth_header = base64.b64encode(auth_string).decode('ascii')
107
+
108
+ request = Request(url, data=data, method='POST')
109
+ request.add_header('Content-Type', 'application/json')
110
+ request.add_header('Authorization', f'Basic {auth_header}')
111
+
112
+ # Send request with timeout
113
+ response = urlopen(request, timeout=5)
114
+
115
+ if 200 <= response.status < 300:
116
+ print(f"[CronRadar] Monitor '{monitor_key}' synced successfully.", file=sys.stderr)
117
+ else:
118
+ print(f"[CronRadar] Failed to sync monitor '{monitor_key}': HTTP {response.status}", file=sys.stderr)
119
+
120
+ except Exception as e:
121
+ print(f"[CronRadar] Error syncing monitor '{monitor_key}': {e}", file=sys.stderr)
122
+ # Never throw - protect user's job execution
123
+
124
+
125
+ def _send_ping_internal(monitor_key: str, api_key: str) -> Optional[int]:
126
+ """Send ping internally and return status code."""
127
+ try:
128
+ from urllib.parse import quote
129
+ url = f"https://api.cronradar.com/ping/{quote(monitor_key, safe='')}"
130
+
131
+ # Prepare request
132
+ auth_string = f"{api_key}:".encode('utf-8')
133
+ auth_header = base64.b64encode(auth_string).decode('ascii')
134
+
135
+ request = Request(url, method='GET')
136
+ request.add_header('Authorization', f'Basic {auth_header}')
137
+
138
+ # Send request with timeout
139
+ response = urlopen(request, timeout=5)
140
+ return response.status
141
+
142
+ except HTTPError as e:
143
+ return e.code
144
+ except Exception:
145
+ return None
146
+
147
+
148
+ def _detect_source() -> str:
149
+ """
150
+ Detect the calling source/framework based on stack trace and imported modules.
151
+
152
+ Returns:
153
+ Source identifier string
154
+ """
155
+ try:
156
+ # Check for Celery
157
+ if 'celery' in sys.modules:
158
+ return 'celery'
159
+
160
+ # Check for Airflow
161
+ if 'airflow' in sys.modules:
162
+ return 'airflow'
163
+
164
+ # Check for APScheduler
165
+ if 'apscheduler' in sys.modules:
166
+ return 'apscheduler'
167
+
168
+ # Check stack trace
169
+ stack = traceback.extract_stack()
170
+ for frame in stack:
171
+ filename = frame.filename.lower()
172
+ if 'celery' in filename:
173
+ return 'celery-direct'
174
+ if 'airflow' in filename:
175
+ return 'airflow-direct'
176
+ if 'django' in filename:
177
+ return 'django-direct'
178
+ if 'flask' in filename:
179
+ return 'flask-direct'
180
+
181
+ except Exception:
182
+ pass
183
+
184
+ return 'manual'
185
+
186
+
187
+ def _generate_readable_name(monitor_key: str) -> str:
188
+ """
189
+ Generate a human-readable name from a monitor key.
190
+ Converts kebab-case or snake_case to Title Case.
191
+
192
+ Args:
193
+ monitor_key: The monitor key
194
+
195
+ Returns:
196
+ Human-readable name
197
+ """
198
+ if not monitor_key:
199
+ return monitor_key
200
+
201
+ # Handle kebab-case: "check-overdue-pings" -> "Check Overdue Pings"
202
+ if '-' in monitor_key:
203
+ return ' '.join(word.capitalize() for word in monitor_key.split('-'))
204
+
205
+ # Handle snake_case: "check_overdue_pings" -> "Check Overdue Pings"
206
+ if '_' in monitor_key:
207
+ return ' '.join(word.capitalize() for word in monitor_key.split('_'))
208
+
209
+ # Handle PascalCase: "CheckOverduePings" -> "Check Overdue Pings"
210
+ if monitor_key and monitor_key[0].isupper():
211
+ import re
212
+ # Insert space before capital letters
213
+ result = re.sub(r'(?<!^)([A-Z])', r' \1', monitor_key)
214
+ return result
215
+
216
+ # Default: just capitalize first letter
217
+ return monitor_key.capitalize()
218
+
219
+
220
+ # Export public API
221
+ __all__ = ['ping', 'sync_monitor', '__version__']
@@ -0,0 +1,76 @@
1
+ Metadata-Version: 2.4
2
+ Name: cronradar
3
+ Version: 0.0.1
4
+ Summary: Dead-simple cron job monitoring with auto-registration. Two functions: ping() and sync_monitor(). Self-healing monitors.
5
+ Home-page: https://github.com/cronradar/cronradar-python
6
+ Author: Administrator
7
+ Author-email: contact@cronradar.com
8
+ License: Proprietary
9
+ Project-URL: Documentation, https://cronradar.com/docs
10
+ Project-URL: Source, https://github.com/cronradar/cronradar-python
11
+ Project-URL: Tracker, https://github.com/cronradar/cronradar-python/issues
12
+ Keywords: cron monitoring scheduler job task ping sync auto-register
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: Other/Proprietary License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Topic :: System :: Monitoring
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Dynamic: author
29
+ Dynamic: author-email
30
+ Dynamic: classifier
31
+ Dynamic: description
32
+ Dynamic: description-content-type
33
+ Dynamic: home-page
34
+ Dynamic: keywords
35
+ Dynamic: license
36
+ Dynamic: license-file
37
+ Dynamic: project-url
38
+ Dynamic: requires-python
39
+ Dynamic: summary
40
+
41
+ # CronRadar Python SDK
42
+
43
+ Monitor cron jobs with one function call.
44
+
45
+ ## Installation
46
+
47
+ ```bash
48
+ pip install cronradar
49
+ ```
50
+
51
+ ## Usage
52
+
53
+ ```python
54
+ import cronradar
55
+
56
+ # After your cron job completes successfully
57
+ cronradar.ping('daily-backup')
58
+
59
+ # With self-healing (auto-register if monitor doesn't exist)
60
+ cronradar.ping('daily-backup', schedule='0 2 * * *', grace_period=300)
61
+ ```
62
+
63
+ ## Configuration
64
+
65
+ Set environment variable:
66
+ - `CRONRADAR_API_KEY`: Your API key from cronradar.com
67
+ - `CRONRADAR_BASE_URL`: Base URL override (optional, default: `https://cronradar.com`)
68
+ - `CRONRADAR_METHOD`: HTTP method for ping (optional, default: `GET`)
69
+
70
+ ## Documentation
71
+
72
+ See [cronradar.com/docs](https://cronradar.com/docs) for full documentation.
73
+
74
+ ## License
75
+
76
+ MIT
@@ -0,0 +1,8 @@
1
+ LICENSE
2
+ README.md
3
+ setup.py
4
+ cronradar/__init__.py
5
+ cronradar.egg-info/PKG-INFO
6
+ cronradar.egg-info/SOURCES.txt
7
+ cronradar.egg-info/dependency_links.txt
8
+ cronradar.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ cronradar
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,38 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ with open("README.md", "r", encoding="utf-8") as fh:
4
+ long_description = fh.read()
5
+
6
+ setup(
7
+ name="cronradar",
8
+ version="0.0.1",
9
+ author="Administrator",
10
+ author_email="contact@cronradar.com",
11
+ description="Dead-simple cron job monitoring with auto-registration. Two functions: ping() and sync_monitor(). Self-healing monitors.",
12
+ long_description=long_description,
13
+ long_description_content_type="text/markdown",
14
+ url="https://github.com/cronradar/cronradar-python",
15
+ project_urls={
16
+ "Documentation": "https://cronradar.com/docs",
17
+ "Source": "https://github.com/cronradar/cronradar-python",
18
+ "Tracker": "https://github.com/cronradar/cronradar-python/issues",
19
+ },
20
+ packages=find_packages(),
21
+ classifiers=[
22
+ "Development Status :: 5 - Production/Stable",
23
+ "Intended Audience :: Developers",
24
+ "License :: Other/Proprietary License",
25
+ "Operating System :: OS Independent",
26
+ "Programming Language :: Python :: 3",
27
+ "Programming Language :: Python :: 3.8",
28
+ "Programming Language :: Python :: 3.9",
29
+ "Programming Language :: Python :: 3.10",
30
+ "Programming Language :: Python :: 3.11",
31
+ "Programming Language :: Python :: 3.12",
32
+ "Topic :: Software Development :: Libraries :: Python Modules",
33
+ "Topic :: System :: Monitoring",
34
+ ],
35
+ python_requires=">=3.8",
36
+ keywords="cron monitoring scheduler job task ping sync auto-register",
37
+ license="Proprietary",
38
+ )