Release Notes¶
0.5.0 (2015-04-18)¶
Major or backward incompatible changes:
Now, multiple values for a client query parameter can be specified in URL query strings in two alternative ways:
- separated with commas, within one query string item (as in past n6sdk versions), e.g.: category=bots,dos-attacker,phish;
- as individual query string items (the way introduced in this n6sdk release), e.g.: category=bots&category=dos-attacker&category=phish.
Implementation of the extension caused the following changes in the n6sdk programming interfaces:
- now, the argument for <data specification>.clean_param_dict() is a dictionary that maps query parameter names to lists of individual uncleaned parameter values (in past n6sdk versions it mapped to strings consisting of comma-separated uncleaned parameter values);
- extraction of individual query parameter values from the URL’s query string – including splitting comma-separated sequences of values – is now entirely outside of the data specification machinery and field classes; the n6sdk.data_spec.fields.Field._split_raw_param_value() non-public method has been removed.
- the interface of the n6sdk.exceptions.ParamValueCleaningError constructor has been extended a bit: now the second item of a 3-tuple being an item of a error_info_seq argument can be either a single value (as previously) or a list of values.
The tutorial and other parts of the documentation have been adjusted appropriately.
Significant changes related to data specification fields:
- New field classes in the n6sdk.data_spec.fields module:
- IPv6Field (for IPv6 addresses),
- IPv6NetField (for IPv6 network specifications),
- EmailSimplifiedField (for e-mail addresses),
- IBANSimplifiedField (for IBAN numbers),
- ListOfDictsField (for lists of dicts containing arbitrary data),
- DirField (two-value enumeration: 'src' or 'dst').
- Modified field classes in the n6sdk.data_spec.fields
module:
- DictResultField:
- the key_to_subfield_factory attribute is no longer obligatory;
- the required_keys attribute is gone;
- the clean_param_value() method now raises TypeError instead of NotImplementedError;
- AddressField:
- now inherits from ListOfDictsField and not directly from ResultListFieldMixin and DictResultField;
- the required_keys attribute is gone; ip subfield is still obligatory – but now this requirement is implemented internally;
- the clean_param_value() method now raises TypeError instead of NotImplementedError.
- DictResultField:
- New field specifications added to the n6sdk.data_spec.DataSpec
class:
- time.until (DateTimeField, params-only),
- active.until (DateTimeField, params-only),
- modified (DateTimeField, results-only),
- modified.min (DateTimeField, params-only),
- modified.max (DateTimeField, params-only),
- modified.until (DateTimeField, params-only),
- ipv6 (IPv6Field, params-only),
- ipv6.net (IPv6NetField, params-only),
- injects (ListOfDictsField, results-only),
- registrar (UnicodeLimitedField),
- url_pattern (UnicodeLimitedField),
- username (UnicodeLimitedField),
- x509fp_sha1 (SHA1Field),
- email (EmailSimplifiedField),
- iban (IBANSimplifiedField),
- phone (UnicodeLimitedField).
- The address field specification (at
n6sdk.data_spec.DataSpec) has been modified: now it is an
ExtendedAddressField instance – its subfields include:
- ip/ipv6 (IPv4Field/IPv6Field, obligatory – which means that either 'ip' or `ipv6', but not both, must be present in each member dictionary),
- cc (CCField),
- asn (ASNField),
- dir (DirField),
- rdns (DomainNameField).
- New categories added to DataSpec.category.enum_values:
- 'amplifier',
- 'backdoor',
- 'dns-query',
- 'flow',
- 'flow-anomaly',
- 'fraud',
- 'leak',
- 'vulnerable',
- 'webinject'.
The tutorial has been adjusted appropriately.
- New field classes in the n6sdk.data_spec.fields module:
Both standard renderers (json and sjson) now add the Z suffix (indicating the UTC time) to all date+time values.
The sjson renderer now generates an additional empty line to indicate the end of data stream.
Other changes:
- A new external dependency: the ipaddr library.
- New and improved unit tests and doctests.
- Several documentation improvements and fixes.
0.4.0 (2014-12-23)¶
This is the first public, free/open-source-licensed release of n6sdk.
Backward incompatible (though rather minor) changes:
- Changed behaviour of the standard json and sjson renderers (defined in n6sdk.pyramid_commons.renderers as the StreamRenderer_json and StreamRenderer_sjson classes): now they make use of a new helper function, dict_with_nulls_removed(), that replaces the old mechanism of recursive removing of None-or-empty values from result dictionaries: previously, values equal to zero (such as 0, 0.0 or False) were also removed; now they are kept (note that values being None, empty containers and empty strings are still removed).
- Now, in the n6sdk.pyramid_commons.DefaultStreamViewBase.call_api() method, an n6sdk.exceptions.TooMuchDataError exception from call_api_method() or from data specification’s clean_result_dict() causes pyramid.httpexceptions.HTTPForbidden and not pyramid.httpexceptions.HTTPServerError.
- The n6sdk.class_helpers.singleton() class decorator is now more lenient: instantiation does not count if __init__() of a decorated class raised (or propagated) an exception.
Other changes:
- Bugfix in the n6sdk.pyramid_commons.DefaultStreamViewBase.concrete_view_class() class method: now the check of the given renderer labels against the set of registered renderers works properly; previously it behaved nonsensically: accepted unregistered labels (causing further KeyError exceptions) and at the same time demanded that all registeted labels had to be used.
- Furthermore, n6sdk.pyramid_commons.DefaultStreamViewBase has a new class attribute: break_on_result_cleaning_error, by default set to True. In custom subclasses it can be set to False – then result dictionaries that cannot be cleaned will be skipped (and a proper warning will be recorded to the logs) instead of causing pyramid.httpexceptions.HTTPServerError.
- The n6sdk.pyramid_commons.renderers.dict_with_nulls_removed() function (mentioned above) is exposed as a public helper (it may be useful when implementing custom renderers).
- The n6sdk.data_spec.fields.Field class (and its subclasses) as well as n6sdk.datetime_helpers.FixedOffsetTimezone – have custom implementations of the __repr__() method (producing more readable results).
- Various minor code cleanups, refactorizations and improvements.
- New and improved unit tests and doctests.
Documentation-related news (including big ones!):
- Now the documentation is generated with Sphinx.
- A new, long tutorial has been added.
- A bunch of docstrings have been added.
- Contents of many docstrings have been improved.
- All docstrings are now reStructuredText-formatted and used as a part of the Sphinx-generated documentation.
- The former CHANGES.txt file has been reStructuredText-formatted, renamed to NEWS.rst and used as a part of the Sphinx-generated documentation. There is also a new README.rst file, also included in the generated documentation.
- The former README.txt file has been moved to examples/BasicExample and sligthly improved.
- Furthermore, some other BasicExample improvements have been made (cleanups, refactorizations and minor fixes; among others, the version field in the BasicExample‘s setup.py file no longer follows the n6sdk version; from now it is just "0.0.1").
0.3.0 (2014-08-12)¶
Major or backward incompatible changes:
- Network incident category "ddos" has been replaced with two separate categories: "dos-attacker" and "dos-victim" (see: n6sdk.data_spec.CATEGORY_ENUMS).
- n6sdk.data_spec.fields.ResultListFieldMixin.clean_result_value() no longer accepts collections.Set instances (now it accepts only collection.Sequence instances that are not str/unicode instances).
0.2.0 (2014-08-08)¶
Major or backward incompatible changes:
Changes in the base data specification class (n6sdk.data_spec.DataSpec) and/or in the classes defined in the n6sdk.data_spec.fields module:
the source field is now an instance of a new class: n6sdk.data_spec.fields.SourceField – which implements more restricted validation of values; now each value not only needs to be at most 32-characters long, but also it must consist of two non-empty parts, separated with exactly one dot character ('.'), containing only lowercase ASCII letters, digits and hyphens ('-').
a change in n6sdk.data_spec.fields.DateTimeField that affects the time, expires and until fields of DataSpec: the clean_result_value() method now accepts also ISO-formatted date-and-time strings (not only datetime.datetime instances);
a change in n6sdk.data_spec.fields.IntegerField that affects the sport, dport and count fields of DataSpec: in clean_result_value(), the former strict is-instance check (int/long) has been replaced with a duck-typed coercion, accepting anything that can be converted using int() without information loss (e.g. a float being an integer number, such as 42.0, or a string being a decimal representation of an integer number, such as '42' – but not '42.0');
a change in n6sdk.data_spec.fields.ASNField that affects the address (namely: asn of its subitems) and asn fields of DataSpec: the clean_*_value() methods now accept strings (str/unicode):
- either being a decimal representation of an integer number in range 0..``2**32-1``, e.g. '98765432' (formely only clean_param_value() accepted such strings),
- or consisting of two dot-separated decimal representations of integer numbers in range 0..``2**16-1``, e.g. '34567.65432' (formely such a notation was not accepted at all);
note: clean_result_value() still accepts also int and long values in range 0..``2**32-1`` (and still does not accept instances of float and other types).
a change in n6sdk.data_spec.fields.CCField that affects the address (namely: cc of its subitems) and cc fields of DataSpec: the clean_*_value() methods now accept also lowercase letters (which are automatically uppercased);
a change in n6sdk.data_spec.fields.DomainNameSubstringField that affects the fqdn (note: DomainNameField is a subclass of DomainNameSubstringField) and fqdn.sub fields of DataSpec: the value of max_length has been changed from 253 to 255;
a change in n6sdk.data_spec.fields.DomainNameField that affects the fqdn field of DataSpec: the regular expression the values are matched against is now more liberal (especially, underscores are now allowed; rationale: real-life domain names – especially those maliciously constructed – are not necessarily RFC-compliant; see: n6sdk.regexes.DOMAIN_ASCII_LOWERCASE_REGEX for details);
a change in n6sdk.data_spec.fields.AnonymizedIPv4Field that affects the adip field of DataSpec: the clean_*_value() methods now accept also 'X' (uppercased 'x') segments which are automatically lowercased;
the adip field is no longer enabled as a query parameter (field’s in_params is now set to None);
a change in n6sdk.data_spec.fields.HexDigestField that affects the md5 and sha1 fields of DataSpec: the clean_*_value() methods now accept also non-lowercase hexadecimal digit letters (which are automatically lowercased);
the former hash_algo attribute of UnicodeField class/subclasses/instances has been renamed to hash_algo_descr;
n6sdk.data_spec.fields.URLField is now a subclass of n6sdk.data_spec.fields.URLSubstringField;
n6sdk.data_spec.fields.ListField has been removed (use ResultListFieldMixin instead);
the former n6sdk.data_spec.fields.AddressField implementation has been replaced with a new one, especially the implementation of the methods has been factored out to new generic base classes: ResultListFieldMixin and DictResultField; some details have changed in a backwards-incompatible way – notably: key_to_subfield_class has been renamed to key_to_subfield_factory.
Changes in signatures of the n6sdk.data_spec.BaseDataSpec methods: clean_param_dict(), clean_param_keys(), clean_result_dict(), clean_result_keys():
- replaced the optional argument keys_to_ignore with the ignored_keys keyword-only argument (still optional),
- added other optional arguments: forbidden_keys, extra_required_keys, discarded_keys.
Changes in n6sdk.pyramid_commons:
functions init_pyramid_config() and complete_pyramid_config() have been removed; use the new ConfigHelper class instead (for details – see its documentation, its code and the examples in examples/BasicExample...);
a new function added: register_stream_renderer() (see below);
the signature of the StreamResponse class constructor changed: renderer has been renamed to renderer_name; also, now the value of that argument can be any name registered with the new function register_stream_renderer() (see its documentation for details); 'json' and 'sjson' are registered out-of-the-box;
the DefaultStreamViewBase class has been revamped in a backward-incompatibile way (please analyze its code if you need detailed information); most notably:
- now the concrete_view_class() class method has completely different signature (see its documentation for details; note that data_spec now must be an instance, not a class); now each concrete subclass must have specified the resource_id, renderers, data_spec and data_backend_api_method attributes (for more information, also see the documentation of the concrete_view_class() class method mentioned above);
- formely, the data specification’s clean_param_dict() call performed in prepare_params() was guarded only against ParamCleaningError (transformed into pyramid.httpexceptions.HTTPBadRequest, when caught); now, also other exceptions are handled: n6sdk.exceptions.AuthorizationError (transformed into pyramid.httpexceptions.HTTPForbidden) and generic n6sdk.exceptions.DataAPIError (logged as an error and transformed into pyramid.httpexceptions.HTTPServerError) [note the symmetry between the prepare_params() and call_api() methods];
- the possibility of specifying keyword arguments for data specification’s clean_*_dict() calls as well as for data backend API’s method call has been added (see the get_clean_param_dict_kwargs(), get_clean_result_dict_kwargs() and get_extra_api_kwargs() hook methods; the default implementation of each of them returns just an empty dict);
backward-incompatibile chages in the signature of the constructor of the HttpResource class:
- now all arguments should be specified as keyword ones (never positional, i.e. you cannot rely on argument order any more);
- now data_spec must be an instance, not a class;
note: see the documentation of this class for details.
The module n6sdk.data_backend_api (together with the decorator n6sdk.data_backend_api.data_backend_api_method) has been removed. It is no longer required to decorate or mark your custom data backend API class or its methods in any special way.
Unused n6sdk.exceptions.InvalidCallError has been removed.
n6sdk.exceptions.FieldValueTooLongError has been added (see below).
Other changes:
- Appropriate adjustments in examples/BasicExample.
- Some non-essential changes related to n6sdk.data_spec.fields:
- if the given value is too long, the clean_*_value() methods of n6sdk.data_spec.fields.UnicodeLimitedField (and of its subclasses) now raise a new exception n6sdk.exceptions.FieldValueTooLongError (which is a subclass of n6sdk.exceptions.FieldValueError that was formely raised) – see its documentation for details about attributes of its instances (that attributes can be useful, for example, when implementing external trimming of too long values...);
- it is now explicitly required for n6sdk.data_spec.fields.HexDigestField instances (and for instances of its subclasses) that num_of_characters and hash_algo_descr are specified (as subclass attributes or constructor arguments);
- it is now explicitly required for n6sdk.data_spec.fields.UnicodeLimitedField instances (and for instances of its subclasses) that max_length is not less than 1.
- Module n6sdk.addr_helpers added.
- Major refactorings and several minor additions, improvements, fixes and cleanups.
- Improvements in the documentation (a lot of improved/added docstrings, improved README.txt, added CHANGES.txt...) and code comments.
- MANIFEST.in and other package setup improvements and cleanups.
- New and improved unit tests and doctests.
0.0.1 (2014-04-25)¶
Initial release.