Skip to content

Commit 64586fe

Browse files
authored
Merge pull request #68 from Worvast/master
## [3.1.0] - 2019-09-25
2 parents af10552 + 4f73b03 commit 64586fe

File tree

11 files changed

+155
-29
lines changed

11 files changed

+155
-29
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

77

8+
## [3.1.0] - 2019-10-21
9+
#### Fixed
10+
* Documentation with examples of version 2.0
11+
12+
#### Added
13+
* level flag to handlers in logging and updated documentation
14+
* flag/capacity of Sender to use pfx certificates
15+
#### Deprecated
16+
* level for global logging when get_log. We maintain general level until version 4
17+
818
## [3.0.3] - 2019-09-25
919
#### Fixed
1020
* Fixed reconnection to socket in every send instruction of Sender

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
[![master Build Status](https://travis-ci.com/DevoInc/python-sdk.svg?branch=master)](https://travis-ci.com/DevoInc/python-sdk) [![LICENSE](https://img.shields.io/dub/l/vibe-d.svg)](https://github.com/DevoInc/python-sdk/blob/master/LICENSE)
33

4-
[![wheel](https://img.shields.io/badge/wheel-yes-brightgreen.svg)](https://pypi.org/project/devo-sdk/) [![version](https://img.shields.io/badge/version-3.0.3-blue.svg)](https://pypi.org/project/devo-sdk/) [![python](https://img.shields.io/badge/python-3.5%20%7C%203.6%20%7C%203.7-blue.svg)](https://pypi.org/project/devo-sdk/)
4+
[![wheel](https://img.shields.io/badge/wheel-yes-brightgreen.svg)](https://pypi.org/project/devo-sdk/) [![version](https://img.shields.io/badge/version-3.1.0-blue.svg)](https://pypi.org/project/devo-sdk/) [![python](https://img.shields.io/badge/python-3.5%20%7C%203.6%20%7C%203.7-blue.svg)](https://pypi.org/project/devo-sdk/)
55

66

77
# Devo Python SDK

devo/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
__description__ = 'Devo Python Library.'
22
__url__ = 'http://www.devo.com'
3-
__version__ = "3.0.3"
3+
__version__ = "3.1.0"
44
__author__ = 'Devo'
55
__author_email__ = 'support@devo.com'
66
__license__ = 'MIT'

devo/api/client.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ def __init__(self, address=None, auth=None, config=None,
129129
Initialize the API with this params, all optionals
130130
:param address: endpoint
131131
:param auth: object with auth params (key, secret, token, jwt)
132-
:param options: options class for Client and queries
133132
:param retries: number of retries for a query
134133
:param timeout: timeout of socket
135134
"""
@@ -293,7 +292,6 @@ def _call(self, payload):
293292
"""
294293
Make the call, select correct item to return
295294
:param payload: item with headers for request
296-
:param stream: boolean, indicate if one call is a streaming call
297295
:return: Response from API
298296
"""
299297
if self.config.stream:

devo/common/logging/log.py

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,27 @@
66
from logging.handlers import RotatingFileHandler
77

88

9-
def get_log(name="log", level=logging.DEBUG, handler=None):
10-
"""Initialize logger for self process log
9+
def get_log(name="log", level=None, handler=None):
10+
"""Initialize logger for self process
11+
:TODO v4.0.0: In version 4.0 delete level option for get_log
1112
:return: Log object
1213
"""
1314
logger = logging.getLogger(name)
14-
logger.addHandler(get_rotating_file_handler()
15-
if not handler else handler)
16-
logger.setLevel(level)
15+
if handler is None:
16+
handler = get_rotating_file_handler(level=None if level is None
17+
else level)
18+
logger.addHandler(handler)
19+
elif isinstance(handler, list):
20+
for simple_handler in handler:
21+
if level is not None:
22+
simple_handler.setLevel(level)
23+
logger.addHandler(simple_handler)
24+
else:
25+
logger.addHandler(handler)
26+
27+
if level is not None:
28+
logger.setLevel(level)
29+
1730
return logger
1831

1932

@@ -29,7 +42,8 @@ def get_rotating_file_handler(path="./",
2942
file_name="history.log",
3043
msg_format='%(asctime)s|%(levelname)s|%(message)s',
3144
max_size=2097152,
32-
backup_count=5):
45+
backup_count=5,
46+
level=logging.INFO):
3347
"""Initialize rotating file handler for logger
3448
3549
:return: RotatingFileHandler object
@@ -41,14 +55,19 @@ def get_rotating_file_handler(path="./",
4155
handler = RotatingFileHandler(full_path, maxBytes=max_size,
4256
backupCount=backup_count)
4357
handler.setFormatter(set_formatter(msg_format))
58+
if level is not None:
59+
handler.setLevel(level)
4460
return handler
4561

4662

4763
def get_stream_handler(dest=sys.stdout,
48-
msg_format='%(asctime)s|%(levelname)s|%(message)s'):
64+
msg_format='%(asctime)s|%(levelname)s|%(message)s',
65+
level=logging.INFO):
4966
"""Initialize stream handlerhandler for logger
5067
:return: StreamHandler object
5168
"""
5269
handler = logging.StreamHandler(dest)
5370
handler.setFormatter(set_formatter(msg_format))
71+
if level is not None:
72+
handler.setLevel(level)
5473
return handler

devo/sender/data.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class SenderConfigSSL:
3434
:param key: (str) key src file
3535
:param cert: (str) cert src file
3636
:param chain: (str) chain src file
37+
:param pkcs: (dict) (path: pfx src file, password: of cert)
3738
3839
>>>sender_config = SenderConfigSSL(address=(SERVER, int(PORT)), key=KEY,
3940
... cert=CERT, chain=CHAIN)
@@ -42,7 +43,8 @@ class SenderConfigSSL:
4243
Sender
4344
4445
"""
45-
def __init__(self, address=None, key=None, cert=None, chain=None):
46+
def __init__(self, address=None, key=None, cert=None, chain=None,
47+
pkcs=None):
4648
if not isinstance(address, tuple):
4749
raise DevoSenderException(
4850
"Devo-SenderConfigSSL| address must be a tuple "
@@ -52,6 +54,7 @@ def __init__(self, address=None, key=None, cert=None, chain=None):
5254
self.key = key
5355
self.cert = cert
5456
self.chain = chain
57+
self.pkcs = pkcs
5558
self.hostname = socket.gethostname()
5659
except Exception as error:
5760
raise DevoSenderException(
@@ -164,6 +167,22 @@ def __connect_ssl(self):
164167
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
165168
self.socket.settimeout(self.socket_timeout)
166169

170+
try:
171+
if self._sender_config.pkcs is not None:
172+
from .pfx_to_pem import pfx_to_pem
173+
pkcs = self._sender_config.pkcs
174+
key, cert, chain = pfx_to_pem(path=pkcs.get("path", None),
175+
password=pkcs.get("password",
176+
None))
177+
178+
self._sender_config.key = key.name
179+
self._sender_config.cert = cert.name
180+
self._sender_config.chain = chain.name
181+
except Exception as error:
182+
self.close()
183+
raise DevoSenderException(
184+
"PFX Certificate read failed: %s" %
185+
str(error))
167186
try:
168187
try:
169188
if self._sender_config.key is not None \
@@ -436,7 +455,7 @@ def for_logging(config=None, con_type=None, tag=None, level=None):
436455
elif isinstance(config, dict):
437456
con.logging['level'] = config.get("verbose_level", 10)
438457
else:
439-
con.logging['level'] = 10
458+
con.logging['level'] = logging.INFO
440459

441460
return con
442461

@@ -465,9 +484,10 @@ def _from_dict(config=None, con_type=None):
465484

466485
if connection_type == "SSL":
467486
return SenderConfigSSL(address=address,
468-
key=config.get("key"),
469-
cert=config.get("cert"),
470-
chain=config.get("chain"))
487+
key=config.get("key", None),
488+
cert=config.get("cert", None),
489+
chain=config.get("chain", None),
490+
pkcs=config.get("pkcs", None))
471491

472492
return SenderConfigTCP(address=address)
473493

devo/sender/pfx_to_pem.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# -*- coding: utf-8 -*-
2+
""" Util function to convert .pfx and .pkcs12 certs to key+cert+chain for
3+
use in Python sockets"""
4+
import tempfile
5+
import OpenSSL.crypto
6+
7+
8+
def pfx_to_pem(path=None, password=None):
9+
"""
10+
Decrypts the .pfx file to be used with requests.
11+
:param path: path to .pfx/.pkcs12 file
12+
:param password: password of certificate
13+
:return: NamedTemporaryFile temp_key, temp_cert, temp_ca paths
14+
"""
15+
temp_key = tempfile.NamedTemporaryFile(suffix='.key')
16+
temp_cert = tempfile.NamedTemporaryFile(suffix='.crt')
17+
temp_ca = tempfile.NamedTemporaryFile(suffix='.crt')
18+
19+
f_key = open(temp_key.name, 'wb')
20+
f_cert = open(temp_cert.name, 'wb')
21+
f_ca = open(temp_ca.name, 'wb')
22+
23+
pfx = open(path, 'rb').read()
24+
p12 = OpenSSL.crypto.load_pkcs12(pfx, password)
25+
26+
f_key.write(OpenSSL.crypto.dump_privatekey(
27+
OpenSSL.crypto.FILETYPE_PEM, p12.get_privatekey()))
28+
f_cert.write(OpenSSL.crypto.dump_certificate(
29+
OpenSSL.crypto.FILETYPE_PEM, p12.get_certificate()))
30+
ca = p12.get_ca_certificates()
31+
if ca is not None:
32+
for cert in ca:
33+
f_ca.write(OpenSSL.crypto.dump_certificate(
34+
OpenSSL.crypto.FILETYPE_PEM, cert))
35+
f_key.close()
36+
f_cert.close()
37+
f_ca.close()
38+
return temp_key, temp_cert, temp_ca

docs/api/api.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@ config = ClientConfig(response="json/compact", stream=False,
7070
api = Client(auth= {"key":"myapikey", "secret":"myapisecret"},
7171
address="https://apiv2-eu.devo.com/search/query",
7272
config=config)
73-
74-
7573
```
7674

7775
#### query() params

docs/common.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,20 @@ This library add utilities for other packages.
3232
Devo commons gives you a function, with enough parameters for your personalization, to get a logging object:
3333

3434
```python
35-
def get_log(name="log", level=logging.DEBUG, handler=None)
35+
def get_log(name="log", level=None, handler=None)
3636
```
3737
By default, handler will be a RotatingFileHandler, named history.log, 5 files, in work folder.
38-
You can use other Handler, by you own or using one of the common package
38+
You can use other Handler, by you own or using one of the common package.
39+
40+
If you set level, all handlers has the same level, if you want different levels, pass level to handlers,
41+
and not to logger.
3942

4043
##### StreamHandler
4144

4245
```python
4346
def get_stream_handler(dest=sys.stdout,
44-
msg_format='%(asctime)s|%(levelname)s|%(message)s')
47+
msg_format='%(asctime)s|%(levelname)s|%(message)s',
48+
level=logging.DEBUG)
4549
```
4650
With this function you will obtain a StreamHandler, by default the whole log will be to stdout.
4751

@@ -60,7 +64,8 @@ def get_rotating_file_handler(path="./",
6064
file_name="history.log",
6165
msg_format='%(asctime)s|%(levelname)s|%(message)s',
6266
max_size=2097152,
63-
backup_count=5):
67+
backup_count=5,
68+
level=logging.DEBUG):
6469
```
6570

6671
You can use this handler like in the StreamHandler example

docs/sender.md

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ Variable descriptions
4747
+ logger **(_string_)**: logger. Default sys.console
4848

4949

50+
Class SenderConfigSSL accept various types of certificates, you has:
51+
52+
+ address **(_tuple_)**: (Server address, port)
53+
+ key **(_str_)**: key src file
54+
+ cert **(_str_)**: cert src file
55+
+ chain **(_str_)**: chain src file
56+
+ pkcs **(_dict_)**: (path: pfx src file, password: of cert)
57+
58+
59+
You can use the collector in some ways:
60+
5061
- With certificates:
5162

5263
```python
@@ -55,6 +66,16 @@ engine_config = SenderConfigSSL(address=(SERVER, PORT),
5566
key=KEY, cert=CERT,chain=CHAIN)
5667
con = Sender(engine_config)
5768
```
69+
70+
or
71+
72+
```python
73+
from devo.sender import SenderConfigSSL, Sender
74+
engine_config = SenderConfigSSL(address=(SERVER, PORT),
75+
pkcs={"path": "tmp/mycert.pfx",
76+
"password": "certpassword"})
77+
con = Sender(engine_config)
78+
```
5879

5980
- Without certificates SSL
6081

@@ -125,7 +146,7 @@ from devo.common import Configuration
125146
from devo.sender import Sender
126147

127148
conf = Configuration("./config.json.example", 'sender')
128-
con = Sender.from_dict(conf)
149+
con = Sender(config=conf)
129150
```
130151

131152
#### Sending data
@@ -400,7 +421,7 @@ from devo.sender import Sender, Lookup
400421
conf = Configuration()
401422
conf.load_config("./config.json.example", 'sender')
402423
conf.load_config("./config.json.example", 'lookup')
403-
con = Sender.from_dict(conf.get("sender"))
424+
con = Sender(config=conf.get("sender"))
404425
lookup = Lookup(name=conf.get('name', "default"), historic_tag=None, con=con)
405426

406427
lookup.send_headers(headers=['KEY', 'HEX', 'COLOR'], key='KEY', event='START')

0 commit comments

Comments
 (0)