Skip to content

Commit ec021c4

Browse files
committed
Bump to v3.20.1
1 parent 015faff commit ec021c4

34 files changed

Lines changed: 588 additions & 180 deletions

PKG-INFO

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Metadata-Version: 2.1
22
Name: blpapi
3-
Version: 3.19.3
3+
Version: 3.20.1
44
Summary: Python SDK for Bloomberg BLPAPI
55
Home-page: http://www.bloomberglabs.com/api/
66
Author: Bloomberg L.P.

changelog.txt

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
Version 3.20.1:
2+
===============
3+
- Support for application identity key (AIK)
4+
The application identity key (AIK) is obtained through Bloomberg for registered
5+
applications. It uniquely identifies the registered application for a given Session
6+
and can be provided by 'SessionOptions.setApplicationIdentityKey'.
7+
8+
- Stability and performance improvements
9+
10+
Version 3.20.0:
11+
===============
12+
- Add SOCKS5 proxy support
13+
Users can configure, per endpoint in `SessionOptions`, a single SOCKS5
14+
proxy host by using `Socks5Config` class. SOCKS5 authentication is not
15+
supported.
16+
17+
- Stability and performance improvements
18+
119
Version 3.19.3:
220
==============
321
- Add 'expected_cpp_sdk_version()' method that returns a minimum compatible
@@ -77,13 +95,13 @@ Version 3.17.0:
7795
to convert a 'Message' to 'dict' with 'Message.toPy'. 'Message's and
7896
'Request's have 'dict'-like behavior with '__getitem__' and
7997
'__setitem__'.
80-
98+
8199
- A new method 'correlationId()' is added to 'blpapi.Message'
82100
A new method 'Message.correlationId()' is added to return the
83101
single CorrelationId associated with the message or None if the
84102
message has no CorrelationIds. If the message has multiple
85103
CorrelationIds, the first one is returned.
86-
104+
87105
- Constants for common used `Names`
88106
A new utility class `blpapi.Names` has been added with common
89107
message names.
@@ -174,7 +192,7 @@ Version 3.15.0:
174192
- Simplified existing multi-phased approach to authorization so that both
175193
token generation and authorization can be done by the SDK.
176194
- If 'AuthOptions' instance is provided to the session through the
177-
newly introduced 'setSessionIdentityOptions' (part of'SessionOptions'),
195+
newly introduced 'setSessionIdentityOptions' (part of 'SessionOptions'),
178196
both token generation and subsequent authorization will be done by the
179197
SDK. Successfully authorized identity would become the default
180198
identity for the session that's used for all future requests unless

examples/demoapps/ApiFieldsExample.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ def main():
9999
if eventType == blpapi.Event.REQUEST_STATUS:
100100
for msg in event:
101101
if msg.messageType() == blpapi.Names.REQUEST_FAILURE:
102-
103102
# Request has failed, exit
104103
print(msg)
105104
done = True
@@ -108,7 +107,6 @@ def main():
108107
blpapi.Event.RESPONSE,
109108
blpapi.Event.PARTIAL_RESPONSE,
110109
]:
111-
112110
processResponse(options.requestType, event)
113111

114112
# Received the final response, no further response events are

examples/demoapps/EntitlementsVerificationRequestResponseExample.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ def _handleException(self, session, _2, exception):
7777
self._stop(session)
7878

7979
def _handleSessionStarted(self, session, _1, _2):
80-
8180
# Add the authorization message handlers after the session
8281
# started to only react to the authorization messages of users,
8382
# i.e., avoid those of the session identity.
@@ -217,7 +216,6 @@ def _distributeResponses(self, userIdentifier, identity):
217216
self._distributeResponse(event, userIdentifier, identity)
218217

219218
def _distributeResponse(self, event, userIdentifier, identity):
220-
221219
for msg in event:
222220
if msg.hasElement(RESPONSE_ERROR, excludeNullElements=True):
223221
continue

examples/demoapps/MultipleRequestsOverrideExample.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212

1313
def main():
14-
1514
parser = ArgumentParser(
1615
formatter_class=RawTextHelpFormatter,
1716
description="Multiple requests with override example",

examples/demoapps/RequestServiceProviderExample.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ def parseCmdLine():
3636

3737

3838
def processEvent(event, session):
39-
4039
print("Server received an event")
4140

4241
if event.eventType() == blpapi.Event.REQUEST:

examples/demoapps/SubscriptionWithEventPollingExample.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ def processSubscriptionEvents(session, maxEvents):
8383
f"Received init paint with RequestId {msg.getRequestId()}"
8484
)
8585
else:
86-
8786
# SESSION_STATUS events can happen at any time and
8887
# should be handled as the session can be terminated,
8988
# e.g. session identity can be revoked at a later

examples/demoapps/UserModeExample.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ def _handleSessionStarted(
7777
_event: blpapi.Event,
7878
_msg: blpapi.Message,
7979
):
80-
8180
# Add the authorization messages handlers after the session
8281
# started to only react to the authorization messages of users,
8382
# i.e., avoid those of the session identity.

examples/demoapps/util/ConnectionAndAuthOptions.py

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from blpapi_import_helper import blpapi
22
from argparse import Action
3+
from collections import namedtuple
34

45

56
_SESSION_IDENTITY_AUTH_OPTIONS = "sessionIdentityAuthOptions"
@@ -69,16 +70,38 @@ def __call__(self, parser, args, values, option_string=None):
6970
setattr(args, _SESSION_IDENTITY_AUTH_OPTIONS, authOptions)
7071

7172

73+
HostPort = namedtuple("HostPort", ["host", "port"])
74+
ServerAddress = namedtuple("ServerAddress", ["endpoint", "socks5"])
75+
76+
7277
class HostAction(Action):
7378
"""The action that parses host options from user input"""
7479

75-
def __call__(self, parser, args, values, option_string=None):
76-
vals = values.split(":", 1)
80+
@staticmethod
81+
def _parseHostPort(parser, value):
82+
vals = value.split(":", 1)
7783
if len(vals) != 2:
84+
parser.error(f"Invalid host option '{value}'")
85+
86+
maxPortValue = 65535
87+
if int(vals[1]) <= 0 or int(vals[1]) > maxPortValue:
88+
parser.error(
89+
f"Invalid port '{value}', value must be 1 through {maxPortValue}"
90+
)
91+
return HostPort(vals[0], vals[1])
92+
93+
def __call__(self, parser, args, values, option_string=None):
94+
endpointSocks5 = values.split("/", 1)
95+
if len(endpointSocks5) == 0 or len(endpointSocks5) > 2:
7896
parser.error(f"Invalid host option '{values}'")
7997

98+
endpoint = HostAction._parseHostPort(parser, endpointSocks5[0])
99+
socks5 = None
100+
if len(endpointSocks5) == 2:
101+
socks5 = HostAction._parseHostPort(parser, endpointSocks5[1])
102+
80103
hosts = getattr(args, self.dest)
81-
hosts.append((vals[0], int(vals[1])))
104+
hosts.append(ServerAddress(endpoint, socks5))
82105

83106

84107
class UserIdIpAction(Action):
@@ -106,8 +129,9 @@ def addConnectionAndAuthOptions(parser, forClientServerSetup=False):
106129
"-H",
107130
"--host",
108131
dest="hosts",
109-
help="server name or IP (default: 127.0.0.1:8194). Can be specified multiple times.",
110-
metavar="host:port",
132+
help="Endpoint host:port and optional SOCKS5 host:port to use to connect"
133+
" (default: localhost:8194). Can be specified multiple times.",
134+
metavar="host:port[/socks5Host:socks5Port]",
111135
action=HostAction,
112136
default=[],
113137
)
@@ -291,18 +315,37 @@ def createSessionOptions(options):
291315
)
292316
else:
293317
sessionOptions = blpapi.SessionOptions()
294-
for idx, host in enumerate(options.hosts):
295-
sessionOptions.setServerAddress(host[0], host[1], idx)
318+
for idx, serverAddress in enumerate(options.hosts):
319+
socks5Config = (
320+
blpapi.Socks5Config(
321+
serverAddress.socks5.host, int(serverAddress.socks5.port)
322+
)
323+
if serverAddress.socks5
324+
else None
325+
)
326+
sessionOptions.setServerAddress(
327+
serverAddress.endpoint.host,
328+
int(serverAddress.endpoint.port),
329+
idx,
330+
socks5Config,
331+
)
296332

297333
if tlsOptions:
298334
sessionOptions.setTlsOptions(tlsOptions)
299335

300336
sessionOptions.setSessionIdentityOptions(
301337
options.sessionIdentityAuthOptions
302338
)
339+
340+
def serverAddressToString(server: ServerAddress):
341+
tostr = ":".join(server.endpoint)
342+
if server.socks5:
343+
tostr = f"{tostr}/{':'.join(server.socks5)}"
344+
return tostr
345+
303346
print(
304347
f"Connecting to "
305-
f"{', '.join([h[0] + ':' + str(h[1]) for h in sessionOptions.serverAddresses()])}"
348+
f"{', '.join([serverAddressToString(h) for h in options.hosts])}"
306349
)
307350

308351
return sessionOptions

examples/demoapps/util/events/SessionRouter.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ def printEvent(event: blpapi.Event):
1111

1212

1313
class SessionRouter:
14-
1514
EventHandler = Callable[[blpapi.AbstractSession, blpapi.Event], None]
1615
MessageHandler = Callable[
1716
[blpapi.AbstractSession, blpapi.Event, blpapi.Message], None

0 commit comments

Comments
 (0)