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.
Files changed (25) hide show
  1. {pihole6api-0.1.0/src/pihole6api.egg-info → pihole6api-0.1.2}/PKG-INFO +3 -3
  2. {pihole6api-0.1.0 → pihole6api-0.1.2}/README.md +3 -3
  3. {pihole6api-0.1.0 → pihole6api-0.1.2}/pyproject.toml +1 -1
  4. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/client.py +5 -1
  5. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/config.py +47 -0
  6. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/conn.py +12 -1
  7. pihole6api-0.1.2/src/pihole6api/metrics.py +189 -0
  8. {pihole6api-0.1.0 → pihole6api-0.1.2/src/pihole6api.egg-info}/PKG-INFO +3 -3
  9. pihole6api-0.1.0/src/pihole6api/metrics.py +0 -79
  10. {pihole6api-0.1.0 → pihole6api-0.1.2}/LICENSE +0 -0
  11. {pihole6api-0.1.0 → pihole6api-0.1.2}/setup.cfg +0 -0
  12. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/__init__.py +0 -0
  13. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/actions.py +0 -0
  14. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/client_management.py +0 -0
  15. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/dhcp.py +0 -0
  16. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/dns_control.py +0 -0
  17. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/domain_management.py +0 -0
  18. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/ftl_info.py +0 -0
  19. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/group_management.py +0 -0
  20. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/list_management.py +0 -0
  21. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api/network_info.py +0 -0
  22. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api.egg-info/SOURCES.txt +0 -0
  23. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api.egg-info/dependency_links.txt +0 -0
  24. {pihole6api-0.1.0 → pihole6api-0.1.2}/src/pihole6api.egg-info/requires.txt +0 -0
  25. {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.0
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.client import PiHole6Client
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.client import PiHole6Client
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).
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pihole6api"
7
- version = "0.1.0"
7
+ version = "0.1.2"
8
8
  description = "Python API Client for Pi-hole 6"
9
9
  authors = [{name = "Shane Barbetta", email = "shane@barbetta.me"}]
10
10
  license = {text = "MIT"}
@@ -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.0
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.client import PiHole6Client
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