Skip to content

Commit 1dfc40f

Browse files
authored
Merge pull request #48 from stephenrauch/Find-Service-Types
Find service types
2 parents 183cd81 + cfbb157 commit 1dfc40f

3 files changed

Lines changed: 75 additions & 0 deletions

File tree

README.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,13 @@ Here's an example:
110110
If you want to customize that you need to specify ``interfaces`` argument when
111111
constructing ``Zeroconf`` object (see the code for details).
112112

113+
If you don't know the name of the service you need to browse for, try:
114+
115+
.. code-block:: python
116+
117+
from zeroconf import ZeroconfServiceTypes
118+
print('\n'.join(ZeroconfServiceTypes.find()))
119+
113120
See examples directory for more.
114121

115122
Changelog

test_zeroconf.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
ServiceInfo,
2222
ServiceStateChange,
2323
Zeroconf,
24+
ZeroconfServiceTypes,
2425
)
2526

2627
log = logging.getLogger('zeroconf')
@@ -159,6 +160,33 @@ def test_bad_service_info_name(self):
159160
browser.close()
160161

161162

163+
class ServiceTypesQuery(unittest.TestCase):
164+
165+
def test_integration_with_listener(self):
166+
167+
type_ = "_test_service_type._tcp.local."
168+
name = "xxxyyy"
169+
registration_name = "%s.%s" % (name, type_)
170+
171+
zeroconf_registrar = Zeroconf(interfaces=['127.0.0.1'])
172+
desc = {'path': '/~paulsm/'}
173+
info = ServiceInfo(
174+
type_, registration_name,
175+
socket.inet_aton("10.0.1.2"), 80, 0, 0,
176+
desc, "ash-2.local.")
177+
zeroconf_registrar.register_service(info)
178+
179+
try:
180+
service_types = ZeroconfServiceTypes.find(timeout=0.5)
181+
assert type_ in service_types
182+
service_types = ZeroconfServiceTypes.find(
183+
zc=zeroconf_registrar, timeout=0.5)
184+
assert type_ in service_types
185+
186+
finally:
187+
zeroconf_registrar.close()
188+
189+
162190
class Listener(unittest.TestCase):
163191

164192
def test_integration_with_listener_class(self):

zeroconf.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,46 @@ def __repr__(self):
12561256
)
12571257

12581258

1259+
class ZeroconfServiceTypes(object):
1260+
"""
1261+
Return all of the advertised services on any local networks
1262+
"""
1263+
def __init__(self):
1264+
self.found_services = set()
1265+
1266+
def add_service(self, zc, type_, name):
1267+
self.found_services.add(name)
1268+
1269+
def remove_service(self, zc, type_, name):
1270+
pass
1271+
1272+
@classmethod
1273+
def find(cls, zc=None, timeout=5):
1274+
"""
1275+
Return all of the advertised services on any local networks.
1276+
1277+
:param zc: Zeroconf() instance. Pass in if already have an
1278+
instance running or if non-default interfaces are needed
1279+
:param timeout: seconds to wait for any responses
1280+
:return: tuple of service type strings
1281+
"""
1282+
local_zc = zc or Zeroconf()
1283+
listener = cls()
1284+
browser = ServiceBrowser(
1285+
local_zc, '_services._dns-sd._udp.local.', listener=listener)
1286+
1287+
# wait for responses
1288+
time.sleep(timeout)
1289+
1290+
# close down anything we opened
1291+
if zc is None:
1292+
local_zc.close()
1293+
else:
1294+
browser.cancel()
1295+
1296+
return tuple(sorted(listener.found_services))
1297+
1298+
12591299
@enum.unique
12601300
class InterfaceChoice(enum.Enum):
12611301
Default = 1

0 commit comments

Comments
 (0)