Skip to content

Commit 9885c59

Browse files
Merge pull request #237 from symphony-soufiane/release-2.0.1
Prepare release 2.0.1
2 parents 7855334 + 0633899 commit 9885c59

File tree

350 files changed

+2666
-432
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

350 files changed

+2666
-432
lines changed

README.md

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
[![FINOS - Incubating](https://cdn.jsdelivr.net/gh/finos/contrib-toolbox@master/images/badge-incubating.svg)](https://finosfoundation.atlassian.net/wiki/display/FINOS/Incubating)
22
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
33
[![Python](https://img.shields.io/badge/python-3.8%20%7C%203.9-blue)](https://www.python.org/downloads/release/python-3)
4-
[![Pypi](https://img.shields.io/badge/pypi-2.0b5-green)](https://pypi.org/project/sym-api-client-python/2.0b5/)
4+
[![Pypi](https://img.shields.io/pypi/v/symphony-bdk-python)](https://pypi.org/project/symphony-bdk-python/)
55
![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/finos/symphony-bdk-python/build/main)
66

77
# Symphony BDK for Python
88

99
This is the Symphony BDK for Python to help develop bots and interact with the [Symphony REST APIs](https://developers.symphony.com/restapi/reference).
1010

11-
Legacy Python BDK is located in the legacy branch of this repo.
12-
1311
## Installation and getting started
1412
The [reference documentation](https://symphony-bdk-python.finos.org/) includes detailed
1513
installation instructions as well as a comprehensive
@@ -33,8 +31,8 @@ To generate locally the Sphinx documentation, run: `cd docsrc && make html`.
3331

3432
## Roadmap
3533

36-
Our next milestone is the [2.0](https://github.com/finos/symphony-bdk-python/milestone/2) one.
37-
It will only consist in delivering an official 2.0.0 version on Pypi under the new package name `symphony-bdk-python`.
34+
Our next milestone is the [2.0.x](https://github.com/finos/symphony-bdk-python/milestone/1) one.
35+
It will only consist in delivering the next improvements of the BDK.
3836

3937

4038
## Contributing

docsrc/index.md

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ Contents
22
--------
33

44
* [Getting Started](markdown/getting_started.md)
5+
* [Migration guide](markdown/migration.md)
56
* [Configuration](markdown/configuration.md)
67
* [Authentication](markdown/authentication.md)
78
* [Datafeed](markdown/datafeed.md)
@@ -35,6 +36,7 @@ If you are just getting started with Symphony Bot developments, you may want to
3536

3637
The reference documentation consists of the following sections:
3738
* [Getting Started](markdown/getting_started.md): Introducing Symphony BDK for beginners
39+
* [Migration guide](markdown/migration.md): Migrating from BDK 1.x to BDK 2.0
3840
* [Configuration](markdown/configuration.md): Configuration structure, formats, how to load from code
3941
* [Authentication](markdown/authentication.md): RSA authentication, OBO authentication
4042
* [Datafeed](markdown/datafeed.md): Listening and reacting to real-time events

docsrc/markdown/configuration.md

+1
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ manager which manages the key token of the bot.
130130
[ssl lib documentation on certificates](https://docs.python.org/3/library/ssl.html#certificates) for more information.
131131

132132
To fetch the cert file in pem format, you can run the following openssl command: `openssl s_client -connect <host>:<port> -showcerts > cert.pem`
133+
If not specified, the BDK will load default system certificates using [SSLContext.load_default_certs](https://docs.python.org/3/library/ssl.html#ssl.SSLContext.load_default_certs).
133134
- `bot` contains information about the bot like the username, the private key for authenticating the service account
134135
on pod.
135136
- `app` contains information about the extension app that the bot will use like

docsrc/markdown/getting_started.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ For all Symphony BDK applications, you should start with the [Symphony Generator
1010
The Symphony Generator offers a fast way to bootstrap your Symphony BDK project in several languages, including Python:
1111
```
1212
npm i -g generator-symphony
13-
yo symphony 2.0
13+
yo symphony
1414
```
1515
After entering pod and bot information and selecting `Bot Application` as application type, you should be able to select
1616
Python as programming language. This will generated a configuration file, a `requirements.txt` and a simple python script.
@@ -33,13 +33,13 @@ setup(
3333
author_email='jane.doe@acme.com',
3434
description='My Python bot',
3535
python_requires='>=3.8',
36-
install_requires=['sym-api-client-python>=2.0b0']
36+
install_requires=['sym-api-client-python>=2.0.0']
3737
)
3838

3939
```
4040
and your `requirements.txt` like:
4141
```
42-
sym-api-client-python>=2.0b0
42+
sym-api-client-python>=2.0.0
4343
```
4444

4545
### Poetry based project
@@ -52,7 +52,7 @@ description = "My bot"
5252

5353
[tool.poetry.dependencies]
5454
python = "^3.8"
55-
sym-api-client-python = "^2.0b0"
55+
sym-api-client-python = "^2.0.0"
5656

5757
[build-system]
5858
requires = ["poetry-core>=1.0.0"]

docsrc/markdown/migration.md

+227
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
# Migration guide to Symphony BDK 2.0
2+
3+
This guide provides information about how to migrate from Symphony BDK 1.0 to BDK 2.0. Migration for the following topics will be detailed here:
4+
- Dependencies
5+
- Bot configuration
6+
- Symphony BDK entry point
7+
- BDK services
8+
- Event listeners
9+
10+
## Dependencies
11+
To use the Python BDK 1.x, you had to use the
12+
[`sym-api-client-python` Pypi package](https://pypi.org/project/sym-api-client-python/) in your `requirements.txt` file.
13+
For the Python BDK 2.0, package name has been changed to [`symphony-bdk-python`](https://pypi.org/project/symphony-bdk-python/).
14+
15+
## Bot configuration
16+
In order for bots to function, a configuration file is needed. Whereas Python BDK 1.x only supports JSON format,
17+
Python BDK 2.0 supports both JSON and YAML formats.
18+
19+
Bot configuration for Python BDK 2.0 should have the following properties:
20+
- `host`: pod host name
21+
- `bot.username`: bot (or service account) username
22+
- `bot.privatekey.path`: path to bot private key file
23+
24+
If your bot is deployed on premise, the following properties are required as well:
25+
- `agent`: on premise agent configuration
26+
- `keyManager`: on premise Key manager configuration
27+
- `proxy`: proxy configuration to reach the pod
28+
- `ssl.trustStore.path`: path to truststore file in PEM format
29+
30+
> Click [here](./configuration.md) for more detailed documentation about BDK configuration.
31+
32+
### Minimal configuration example
33+
34+
#### Using the BDK 1.x
35+
```json
36+
{
37+
"sessionAuthHost": "acme.symphony.com",
38+
"keyAuthHost": "acme.symphony.com",
39+
"podHost": "acme.symphony.com",
40+
"agentHost": "acme.symphony.com",
41+
"botUsername": "bot-username",
42+
"botPrivateKeyPath": "/folder/to/private/key/",
43+
"botPrivateKeyName": "rsa-privatekey.pem",
44+
"truststorePath": ""
45+
}
46+
```
47+
48+
#### Using the BDK 2.0
49+
In JSON:
50+
```json
51+
{
52+
"host": "acme.symphony.com",
53+
"bot": {
54+
"username": "bot-username",
55+
"privateKey": {
56+
"path": "/folder/to/private/key/rsa-privatekey.pem"
57+
}
58+
}
59+
}
60+
```
61+
Or in YAML:
62+
```yaml
63+
host: acme.symphony.com
64+
bot:
65+
username: bot-username
66+
privateKey:
67+
path: "/folder/to/private/key/rsa-privatekey.pem"
68+
```
69+
70+
## Symphony BDK entry point
71+
72+
For the BDK 1.x, `SymBotClient` object acts as an entry point for all services, whereas for the BDK 2.0, it is the `SymphonyBdk` object.
73+
Whereas the BDK 1.x exposes synchronous methods, the BDK 2.0 exposes most of the service methods as `async` methods.
74+
Therefore, an `asyncio` loop is needed to use the BDK.
75+
76+
Please check below for examples or check the [getting started](./getting_started.md) guide.
77+
78+
## BDK services
79+
To illustrate the use of services, let's take an example of a bot reacting to *ping pong* messages.
80+
81+
### Using the BDK 1.x
82+
83+
```python
84+
from sym_api_client_python.auth.rsa_auth import SymBotRSAAuth
85+
from sym_api_client_python.clients.sym_bot_client import SymBotClient
86+
from sym_api_client_python.configure.configure import SymConfig
87+
from sym_api_client_python.listeners.im_listener import IMListener
88+
from sym_api_client_python.processors.sym_message_parser import SymMessageParser
89+
90+
91+
class PingPongListener(IMListener):
92+
def __init__(self, sym_bot_client):
93+
self.bot_client = sym_bot_client
94+
self.message_parser = SymMessageParser()
95+
96+
def on_im_message(self, im_message):
97+
stream_id = self.message_parser.get_stream_id(im_message)
98+
message_text = self.message_parser.get_text(im_message)[0]
99+
100+
if message_text == "/ping":
101+
self._send_message(stream_id, "pong")
102+
elif message_text == "/pong":
103+
self._send_message(stream_id, "ping")
104+
else:
105+
self._send_message(stream_id, "Sorry, I don't understand!")
106+
107+
def on_im_created(self, im_created):
108+
pass
109+
110+
def _send_message(self, stream_id, message):
111+
self.bot_client.get_message_client().send_msg(stream_id, dict(message=message))
112+
113+
114+
def main():
115+
# Load configuration
116+
configure = SymConfig('../resources/config.json')
117+
configure.load_config()
118+
119+
# authenticate
120+
auth = SymBotRSAAuth(configure)
121+
auth.authenticate()
122+
123+
bot_client = SymBotClient(auth, configure)
124+
125+
datafeed_event_service = bot_client.get_datafeed_event_service()
126+
datafeed_event_service.add_im_listener(PingPongListener(bot_client))
127+
128+
print('Starting datafeed')
129+
try:
130+
datafeed_event_service.start_datafeed()
131+
except (KeyboardInterrupt, SystemExit):
132+
print('Stopping datafeed')
133+
134+
135+
if __name__ == "__main__":
136+
main()
137+
```
138+
139+
### Using the BDK 2.0
140+
141+
```python
142+
import asyncio
143+
144+
from symphony.bdk.core.config.loader import BdkConfigLoader
145+
from symphony.bdk.core.service.datafeed.real_time_event_listener import RealTimeEventListener
146+
from symphony.bdk.core.service.message.message_parser import get_text_content_from_message
147+
from symphony.bdk.core.symphony_bdk import SymphonyBdk
148+
from symphony.bdk.gen.agent_model.v4_initiator import V4Initiator
149+
from symphony.bdk.gen.agent_model.v4_message_sent import V4MessageSent
150+
151+
152+
class PingPongListener(RealTimeEventListener):
153+
154+
def __init__(self, message_service):
155+
self._message_service = message_service
156+
157+
async def on_message_sent(self, initiator: V4Initiator, event: V4MessageSent):
158+
message_text = get_text_content_from_message(event.message)
159+
stream_id = event.message.stream.stream_id
160+
if message_text == "/ping":
161+
await self._message_service.send_message(stream_id=stream_id, message="pong")
162+
elif message_text == "/pong":
163+
await self._message_service.send_message(stream_id=stream_id, message="ping")
164+
else:
165+
await self._message_service.send_message(stream_id=stream_id, message="Sorry, I don't understand!")
166+
167+
168+
async def run():
169+
config = BdkConfigLoader.load_from_symphony_dir("config.yaml")
170+
171+
async with SymphonyBdk(config) as bdk:
172+
datafeed_loop = bdk.datafeed()
173+
datafeed_loop.subscribe(PingPongListener(bdk.messages()))
174+
await datafeed_loop.start()
175+
176+
177+
if __name__ == "__main__":
178+
try:
179+
print("Running datafeed example...")
180+
asyncio.run(run())
181+
except KeyboardInterrupt:
182+
print("Ending datafeed example")
183+
```
184+
185+
## Event listeners
186+
187+
### Using the BDK 1.x
188+
In the Python BDK 1.x, we have three main types of listeners:
189+
- for IM (1 to 1 conversation)
190+
- for MIM (room)
191+
- for Symphony elements
192+
193+
There are also listener types for:
194+
- for connection requests
195+
- for wall posts
196+
- for message suppression
197+
198+
See [datafeed_event_service](https://github.com/finos/symphony-bdk-python/blob/legacy/sym_api_client_python/datafeed_event_service.py) for more details.
199+
200+
### Using the BDK 2.0
201+
In the Python BDK 2.0, we have a [`RealTimeEventListener`](../_autosummary/symphony.bdk.core.service.datafeed.real_time_event_listener.RealTimeEventListener.html)
202+
type that listens to all events. Only events you are interested
203+
in needs to have the corresponding method overridden. See [datafeed](./datafeed.md) documentation for more information.
204+
205+
The BDK 2.0 also provides a simple way to listen for `MESSAGESENT` events thanks to activities.
206+
See the [dedicated page](./activity-api.md) on how to use it.
207+
208+
## Message parsing functions
209+
210+
The Python BDK 1.x provides utility modules to parse elements and messages.
211+
The [sym_elements_parser module](https://github.com/finos/symphony-bdk-python/blob/legacy/sym_api_client_python/processors/sym_elements_parser.py)
212+
has no replacement in the BDK 2.0 since method `on_symphony_elements_action` of
213+
[`RealTimeEventListener`](../_autosummary/symphony.bdk.core.service.datafeed.real_time_event_listener.RealTimeEventListener.html)
214+
already returned a structured object of type `V4SymphonyElementsAction`.
215+
216+
However, the [sym_elements_parser](https://github.com/finos/symphony-bdk-python/blob/legacy/sym_api_client_python/processors/sym_elements_parser.py)
217+
is replaced by [message_parser](../_autosummary/symphony.bdk.core.service.message.message_parser.html#module-symphony.bdk.core.service.message.message_parser)
218+
which contains methods to extract cashtags, emojis, hashtags, mentions and the text content.
219+
220+
## Models
221+
Models names have been changed in Python BDK 2.0. They actually follow the models in the openapi specification of
222+
[Symphony's public API](https://github.com/symphonyoss/symphony-api-spec). Field names in Python classes correspond to
223+
the field names in API's JSON payloads. This requires to change some variable types in your legacy bots.
224+
225+
Whereas most of the objects used in the Python BDK 1.x are Python dictionaries, the Python BDK 2.0 leverages objects
226+
generated from the openapi specifications. All public methods exposed by the BDK have type hints so that you can easily
227+
know which types are used as parameters or returned. You can also check the generated documentation [here](../_autosummary/symphony.bdk.core.html).

0 commit comments

Comments
 (0)