pihole6api 0.1.0__tar.gz → 0.1.2__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {pihole6api-0.1.0/src/pihole6api.egg-info → pihole6api-0.1.2}/PKG-INFO +3 -3
- {pihole6api-0.1.0 → pihole6api-0.1.2}/README.md +3 -3
- {pihole6api-0.1.0 → pihole6api-0.1.2}/pyproject.toml +1 -1
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/client.py +5 -1
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/config.py +47 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/conn.py +12 -1
- pihole6api-0.1.2/src/pihole6api/metrics.py +189 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2/src/pihole6api.egg-info}/PKG-INFO +3 -3
- pihole6api-0.1.0/src/pihole6api/metrics.py +0 -79
- {pihole6api-0.1.0 → pihole6api-0.1.2}/LICENSE +0 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/setup.cfg +0 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/__init__.py +0 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/actions.py +0 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/client_management.py +0 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/dhcp.py +0 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/dns_control.py +0 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/domain_management.py +0 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/ftl_info.py +0 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/group_management.py +0 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/list_management.py +0 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/network_info.py +0 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api.egg-info/SOURCES.txt +0 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api.egg-info/dependency_links.txt +0 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api.egg-info/requires.txt +0 -0
- {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: pihole6api
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.2
|
4
4
|
Summary: Python API Client for Pi-hole 6
|
5
5
|
Author-email: Shane Barbetta <shane@barbetta.me>
|
6
6
|
License: MIT
|
@@ -23,7 +23,7 @@ Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
24
24
|
Requires-Dist: requests>=2.26.0
|
25
25
|
|
26
|
-
# pihole6api
|
26
|
+
# 🍓 pihole6api
|
27
27
|
|
28
28
|
This package provides a simple, modular SDK for the PiHole 6 REST API.
|
29
29
|
|
@@ -55,7 +55,7 @@ pip install -e .
|
|
55
55
|
### Initialize the Client
|
56
56
|
|
57
57
|
```python
|
58
|
-
from pihole6api
|
58
|
+
from pihole6api import PiHole6Client
|
59
59
|
client = PiHole6Client("https://your-pihole.local/", "your-password")
|
60
60
|
```
|
61
61
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# pihole6api
|
1
|
+
# 🍓 pihole6api
|
2
2
|
|
3
3
|
This package provides a simple, modular SDK for the PiHole 6 REST API.
|
4
4
|
|
@@ -30,7 +30,7 @@ pip install -e .
|
|
30
30
|
### Initialize the Client
|
31
31
|
|
32
32
|
```python
|
33
|
-
from pihole6api
|
33
|
+
from pihole6api import PiHole6Client
|
34
34
|
client = PiHole6Client("https://your-pihole.local/", "your-password")
|
35
35
|
```
|
36
36
|
|
@@ -109,4 +109,4 @@ client.actions.restart_dns()
|
|
109
109
|
|
110
110
|
## License
|
111
111
|
|
112
|
-
This project is license under the [MIT license](LICENSE).
|
112
|
+
This project is license under the [MIT license](LICENSE).
|
@@ -41,4 +41,8 @@ class PiHole6Client:
|
|
41
41
|
:param full: Boolean flag to get the full dataset.
|
42
42
|
:return: API response containing PADD summary.
|
43
43
|
"""
|
44
|
-
return self.connection.get("padd", params={"full": str(full).lower()})
|
44
|
+
return self.connection.get("padd", params={"full": str(full).lower()})
|
45
|
+
|
46
|
+
def close_session(self):
|
47
|
+
"""Close the Pi-hole session by calling the exit method in the connection."""
|
48
|
+
return self.connection.exit()
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import json
|
2
|
+
import urllib.parse
|
2
3
|
|
3
4
|
class PiHole6Configuration:
|
4
5
|
def __init__(self, connection):
|
@@ -77,3 +78,49 @@ class PiHole6Configuration:
|
|
77
78
|
:return: API response confirming the deletion.
|
78
79
|
"""
|
79
80
|
return self.connection.delete(f"config/{element}/{value}")
|
81
|
+
|
82
|
+
def add_local_a_record(self, host, ip):
|
83
|
+
"""
|
84
|
+
Add a local A record to Pi-hole.
|
85
|
+
|
86
|
+
:param host: The hostname (e.g., "foo.dev")
|
87
|
+
:param ip: The IP address (e.g., "192.168.1.1")
|
88
|
+
:return: API response
|
89
|
+
"""
|
90
|
+
encoded_value = urllib.parse.quote(f"{ip} {host}")
|
91
|
+
return self.connection.put(f"config/dns/hosts/{encoded_value}")
|
92
|
+
|
93
|
+
def remove_local_a_record(self, host, ip):
|
94
|
+
"""
|
95
|
+
Remove a local A record from Pi-hole.
|
96
|
+
|
97
|
+
:param host: The hostname (e.g., "foo.dev")
|
98
|
+
:param ip: The IP address (e.g., "192.168.1.1")
|
99
|
+
:return: API response
|
100
|
+
"""
|
101
|
+
encoded_value = urllib.parse.quote(f"{ip} {host}")
|
102
|
+
return self.connection.delete(f"config/dns/hosts/{encoded_value}")
|
103
|
+
|
104
|
+
def add_local_cname(self, host, target, ttl=300):
|
105
|
+
"""
|
106
|
+
Add a local CNAME record to Pi-hole.
|
107
|
+
|
108
|
+
:param host: The CNAME alias (e.g., "bar.xyz")
|
109
|
+
:param target: The target hostname (e.g., "foo.dev")
|
110
|
+
:param ttl: Time-to-live for the record (default: 300)
|
111
|
+
:return: API response
|
112
|
+
"""
|
113
|
+
encoded_value = urllib.parse.quote(f"{host},{target},{ttl}")
|
114
|
+
return self.connection.put(f"config/dns/cnameRecords/{encoded_value}")
|
115
|
+
|
116
|
+
def remove_local_cname(self, host, target, ttl=300):
|
117
|
+
"""
|
118
|
+
Remove a local CNAME record from Pi-hole.
|
119
|
+
|
120
|
+
:param host: The CNAME alias (e.g., "bar.xyz")
|
121
|
+
:param target: The target hostname (e.g., "foo.dev")
|
122
|
+
:param ttl: Time-to-live for the record (default: 300)
|
123
|
+
:return: API response
|
124
|
+
"""
|
125
|
+
encoded_value = urllib.parse.quote(f"{host},{target},{ttl}")
|
126
|
+
return self.connection.delete(f"config/dns/cnameRecords/{encoded_value}")
|
@@ -124,4 +124,15 @@ class PiHole6Connection:
|
|
124
124
|
|
125
125
|
def patch(self, endpoint, data=None):
|
126
126
|
"""Send a PATCH request."""
|
127
|
-
return self._do_call("PATCH", endpoint, data=data)
|
127
|
+
return self._do_call("PATCH", endpoint, data=data)
|
128
|
+
|
129
|
+
def exit(self):
|
130
|
+
"""Delete the current session."""
|
131
|
+
response = self.delete("auth")
|
132
|
+
|
133
|
+
# Clear stored session info
|
134
|
+
self.session_id = None
|
135
|
+
self.csrf_token = None
|
136
|
+
self.validity = None
|
137
|
+
|
138
|
+
return response
|
@@ -0,0 +1,189 @@
|
|
1
|
+
class PiHole6Metrics:
|
2
|
+
def __init__(self, connection):
|
3
|
+
"""
|
4
|
+
Handles Pi-hole metrics and stats API endpoints.
|
5
|
+
:param connection: Instance of PiHole6Connection for API requests.
|
6
|
+
"""
|
7
|
+
self.connection = connection
|
8
|
+
|
9
|
+
# History API Endpoints
|
10
|
+
def get_history(self):
|
11
|
+
"""Get activity graph data"""
|
12
|
+
return self.connection.get("history")
|
13
|
+
|
14
|
+
def get_history_clients(self, clients=20):
|
15
|
+
"""
|
16
|
+
Get per-client activity graph data
|
17
|
+
|
18
|
+
:param num: Number of clients to return, 0 will return all clients
|
19
|
+
"""
|
20
|
+
params = {"n": clients}
|
21
|
+
return self.connection.get("history/clients", params=params)
|
22
|
+
|
23
|
+
def get_history_database(self, start, end):
|
24
|
+
"""
|
25
|
+
Get long-term activity graph data
|
26
|
+
|
27
|
+
:param start: Start date in unix timestamp format
|
28
|
+
:param end: End date in unix timestamp format
|
29
|
+
"""
|
30
|
+
params = {"from": start, "until": end}
|
31
|
+
return self.connection.get("history/database", params=params)
|
32
|
+
|
33
|
+
def get_history_database_clients(self, start, end):
|
34
|
+
"""
|
35
|
+
Get per-client long-term activity graph data
|
36
|
+
|
37
|
+
:param start: Start date in unix timestamp format
|
38
|
+
:param end: End date in unix timestamp format
|
39
|
+
"""
|
40
|
+
params = {"from": start, "until": end}
|
41
|
+
return self.connection.get("history/database/clients", params=params)
|
42
|
+
|
43
|
+
# Query API Endpoints
|
44
|
+
def get_queries(self, n=100, from_ts=None, until_ts=None, upstream=None, domain=None, client=None, cursor=None):
|
45
|
+
"""
|
46
|
+
Get query log with optional filtering parameters.
|
47
|
+
|
48
|
+
:param int n: Number of queries to retrieve (default: 100).
|
49
|
+
:param int from_ts: Unix timestamp to filter queries from this time onward (optional).
|
50
|
+
:param int until_ts: Unix timestamp to filter queries up to this time (optional).
|
51
|
+
:param str upstream: Filter queries sent to a specific upstream destination (optional).
|
52
|
+
:param str domain: Filter queries for specific domains, supports wildcards `*` (optional).
|
53
|
+
:param str client: Filter queries originating from a specific client (optional).
|
54
|
+
:param str cursor: Cursor for pagination to fetch the next chunk of results (optional).
|
55
|
+
"""
|
56
|
+
params = {
|
57
|
+
"n": n,
|
58
|
+
"from": from_ts,
|
59
|
+
"until": until_ts,
|
60
|
+
"upstream": upstream,
|
61
|
+
"domain": domain,
|
62
|
+
"client": client,
|
63
|
+
"cursor": cursor
|
64
|
+
}
|
65
|
+
params = {k: v for k, v in params.items() if v is not None}
|
66
|
+
return self.connection.get("queries", params=params)
|
67
|
+
|
68
|
+
|
69
|
+
def get_query_suggestions(self):
|
70
|
+
"""Get query filter suggestions"""
|
71
|
+
return self.connection.get("queries/suggestions")
|
72
|
+
|
73
|
+
# Stats Database API Endpoints
|
74
|
+
def get_stats_database_query_types(self, start, end):
|
75
|
+
"""
|
76
|
+
Get query types (long-term database)
|
77
|
+
|
78
|
+
:param start: Start date in unix timestamp format
|
79
|
+
:param end: End date in unix timestamp format
|
80
|
+
"""
|
81
|
+
params = {"from": start, "until": end}
|
82
|
+
return self.connection.get("stats/database/query_types", params=params)
|
83
|
+
|
84
|
+
def get_stats_database_summary(self, start, end):
|
85
|
+
"""
|
86
|
+
Get database content details
|
87
|
+
|
88
|
+
:param start: Start date in unix timestamp format
|
89
|
+
:param end: End date in unix timestamp format
|
90
|
+
"""
|
91
|
+
params = {"from": start, "until": end}
|
92
|
+
return self.connection.get("stats/database/summary", params=params)
|
93
|
+
|
94
|
+
def get_stats_database_top_clients(self, start, end, blocked=None, count=None):
|
95
|
+
"""
|
96
|
+
Get top clients (long-term database).
|
97
|
+
|
98
|
+
:param int start: Start date in Unix timestamp format.
|
99
|
+
:param int end: End date in Unix timestamp format.
|
100
|
+
:param bool blocked: Return information about permitted or blocked queries (optional).
|
101
|
+
:param int count: Number of requested items (optional).
|
102
|
+
"""
|
103
|
+
params = {
|
104
|
+
"from": start,
|
105
|
+
"until": end,
|
106
|
+
"blocked": str(blocked).lower() if blocked is not None else None,
|
107
|
+
"count": count
|
108
|
+
}
|
109
|
+
params = {k: v for k, v in params.items() if v is not None}
|
110
|
+
return self.connection.get("stats/database/top_clients", params=params)
|
111
|
+
|
112
|
+
def get_stats_database_top_domains(self, start, end, blocked=None, count=None):
|
113
|
+
"""
|
114
|
+
Get top domains (long-term database)
|
115
|
+
|
116
|
+
:param int start: Start date in Unix timestamp format.
|
117
|
+
:param int end: End date in Unix timestamp format.
|
118
|
+
:param bool blocked: Return information about permitted or blocked queries (optional).
|
119
|
+
:param int count: Number of requested items (optional).
|
120
|
+
"""
|
121
|
+
params = {
|
122
|
+
"from": start,
|
123
|
+
"until": end,
|
124
|
+
"blocked": str(blocked).lower() if blocked is not None else None,
|
125
|
+
"count": count
|
126
|
+
}
|
127
|
+
params = {k: v for k, v in params.items() if v is not None}
|
128
|
+
return self.connection.get("stats/database/top_domains", params=params)
|
129
|
+
|
130
|
+
def get_stats_database_upstreams(self, start, end):
|
131
|
+
"""
|
132
|
+
Get upstream metrics (long-term database)
|
133
|
+
|
134
|
+
:param start: Start date in unix timestamp format
|
135
|
+
:param end: End date in unix timestamp format
|
136
|
+
"""
|
137
|
+
params = {"from": start, "until": end}
|
138
|
+
return self.connection.get("stats/database/upstreams", params=params)
|
139
|
+
|
140
|
+
# Stats API Endpoints
|
141
|
+
def get_stats_query_types(self):
|
142
|
+
"""Get current query types"""
|
143
|
+
return self.connection.get("stats/query_types")
|
144
|
+
|
145
|
+
def get_stats_recent_blocked(self, count=None):
|
146
|
+
"""
|
147
|
+
Get most recently blocked domain
|
148
|
+
|
149
|
+
:param int count: Number of requested items (optional).
|
150
|
+
"""
|
151
|
+
params = {"count": count}
|
152
|
+
params = {k: v for k, v in params.items() if v is not None}
|
153
|
+
return self.connection.get("stats/recent_blocked", params=params)
|
154
|
+
|
155
|
+
def get_stats_summary(self):
|
156
|
+
"""Get an overview of Pi-hole activity"""
|
157
|
+
return self.connection.get("stats/summary")
|
158
|
+
|
159
|
+
def get_stats_top_clients(self, blocked=None, count=None):
|
160
|
+
"""
|
161
|
+
Get top clients
|
162
|
+
|
163
|
+
:param bool blocked: Return information about permitted or blocked queries (optional).
|
164
|
+
:param int count: Number of requested items (optional).
|
165
|
+
"""
|
166
|
+
params = {
|
167
|
+
"blocked": str(blocked).lower() if blocked is not None else None,
|
168
|
+
"count": count
|
169
|
+
}
|
170
|
+
params = {k: v for k, v in params.items() if v is not None}
|
171
|
+
return self.connection.get("stats/top_clients", params=params)
|
172
|
+
|
173
|
+
def get_stats_top_domains(self, blocked=None, count=None):
|
174
|
+
"""
|
175
|
+
Get top domains
|
176
|
+
|
177
|
+
:param bool blocked: Return information about permitted or blocked queries (optional).
|
178
|
+
:param int count: Number of requested items (optional).
|
179
|
+
"""
|
180
|
+
params = {
|
181
|
+
"blocked": str(blocked).lower() if blocked is not None else None,
|
182
|
+
"count": count
|
183
|
+
}
|
184
|
+
params = {k: v for k, v in params.items() if v is not None}
|
185
|
+
return self.connection.get("stats/top_domains", params=params)
|
186
|
+
|
187
|
+
def get_stats_upstreams(self):
|
188
|
+
"""Get upstream destinations"""
|
189
|
+
return self.connection.get("stats/upstreams")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: pihole6api
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.2
|
4
4
|
Summary: Python API Client for Pi-hole 6
|
5
5
|
Author-email: Shane Barbetta <shane@barbetta.me>
|
6
6
|
License: MIT
|
@@ -23,7 +23,7 @@ Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
24
24
|
Requires-Dist: requests>=2.26.0
|
25
25
|
|
26
|
-
# pihole6api
|
26
|
+
# 🍓 pihole6api
|
27
27
|
|
28
28
|
This package provides a simple, modular SDK for the PiHole 6 REST API.
|
29
29
|
|
@@ -55,7 +55,7 @@ pip install -e .
|
|
55
55
|
### Initialize the Client
|
56
56
|
|
57
57
|
```python
|
58
|
-
from pihole6api
|
58
|
+
from pihole6api import PiHole6Client
|
59
59
|
client = PiHole6Client("https://your-pihole.local/", "your-password")
|
60
60
|
```
|
61
61
|
|
@@ -1,79 +0,0 @@
|
|
1
|
-
class PiHole6Metrics:
|
2
|
-
def __init__(self, connection):
|
3
|
-
"""
|
4
|
-
Handles Pi-hole metrics and stats API endpoints.
|
5
|
-
:param connection: Instance of PiHole6Connection for API requests.
|
6
|
-
"""
|
7
|
-
self.connection = connection
|
8
|
-
|
9
|
-
# History API Endpoints
|
10
|
-
def get_history(self):
|
11
|
-
"""Get activity graph data"""
|
12
|
-
return self.connection.get("history")
|
13
|
-
|
14
|
-
def get_history_clients(self):
|
15
|
-
"""Get per-client activity graph data"""
|
16
|
-
return self.connection.get("history/clients")
|
17
|
-
|
18
|
-
def get_history_database(self):
|
19
|
-
"""Get long-term activity graph data"""
|
20
|
-
return self.connection.get("history/database")
|
21
|
-
|
22
|
-
def get_history_database_clients(self):
|
23
|
-
"""Get per-client long-term activity graph data"""
|
24
|
-
return self.connection.get("history/database/clients")
|
25
|
-
|
26
|
-
# Query API Endpoints
|
27
|
-
def get_queries(self):
|
28
|
-
"""Get query log"""
|
29
|
-
return self.connection.get("queries")
|
30
|
-
|
31
|
-
def get_query_suggestions(self):
|
32
|
-
"""Get query filter suggestions"""
|
33
|
-
return self.connection.get("queries/suggestions")
|
34
|
-
|
35
|
-
# Stats Database API Endpoints
|
36
|
-
def get_stats_database_query_types(self):
|
37
|
-
"""Get query types (long-term database)"""
|
38
|
-
return self.connection.get("stats/database/query_types")
|
39
|
-
|
40
|
-
def get_stats_database_summary(self):
|
41
|
-
"""Get database content details"""
|
42
|
-
return self.connection.get("stats/database/summary")
|
43
|
-
|
44
|
-
def get_stats_database_top_clients(self):
|
45
|
-
"""Get top clients (long-term database)"""
|
46
|
-
return self.connection.get("stats/database/top_clients")
|
47
|
-
|
48
|
-
def get_stats_database_top_domains(self):
|
49
|
-
"""Get top domains (long-term database)"""
|
50
|
-
return self.connection.get("stats/database/top_domains")
|
51
|
-
|
52
|
-
def get_stats_database_upstreams(self):
|
53
|
-
"""Get upstream metrics (long-term database)"""
|
54
|
-
return self.connection.get("stats/database/upstreams")
|
55
|
-
|
56
|
-
# Stats API Endpoints
|
57
|
-
def get_stats_query_types(self):
|
58
|
-
"""Get current query types"""
|
59
|
-
return self.connection.get("stats/query_types")
|
60
|
-
|
61
|
-
def get_stats_recent_blocked(self):
|
62
|
-
"""Get most recently blocked domain"""
|
63
|
-
return self.connection.get("stats/recent_blocked")
|
64
|
-
|
65
|
-
def get_stats_summary(self):
|
66
|
-
"""Get an overview of Pi-hole activity"""
|
67
|
-
return self.connection.get("stats/summary")
|
68
|
-
|
69
|
-
def get_stats_top_clients(self):
|
70
|
-
"""Get top clients"""
|
71
|
-
return self.connection.get("stats/top_clients")
|
72
|
-
|
73
|
-
def get_stats_top_domains(self):
|
74
|
-
"""Get top domains"""
|
75
|
-
return self.connection.get("stats/top_domains")
|
76
|
-
|
77
|
-
def get_stats_upstreams(self):
|
78
|
-
"""Get upstream destinations"""
|
79
|
-
return self.connection.get("stats/upstreams")
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|