From 49988bf59ca78ae96bea2cb000c5f19b3b43cdcd Mon Sep 17 00:00:00 2001 From: Sam Clift Date: Thu, 11 Dec 2014 15:31:31 +0000 Subject: [PATCH 01/14] add initial JSON section --- docs/contents.rst.inc | 1 + docs/scenarios/json.rst | 138 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 docs/scenarios/json.rst diff --git a/docs/contents.rst.inc b/docs/contents.rst.inc index 8e8cd73..cc38532 100644 --- a/docs/contents.rst.inc +++ b/docs/contents.rst.inc @@ -59,6 +59,7 @@ different scenarios. scenarios/scientific scenarios/imaging scenarios/xml + scenarios/json scenarios/crypto diff --git a/docs/scenarios/json.rst b/docs/scenarios/json.rst new file mode 100644 index 0000000..3683eec --- /dev/null +++ b/docs/scenarios/json.rst @@ -0,0 +1,138 @@ +JSON parsing +=========== + +json +----- + +`json `_ is a standard libary which can convert JSON to a Dictionay. + +For example, a JSON string like this: + +.. code-block:: python + + "{'first_name':'Guido','last_name':'Rossum'}" + +can be loaded like this: + +.. code-block:: python + + import json + converted_dict = json.loads(json_string) + +you can now use it as a normal dictionary: + +.. code-block:: python + + converted_dict['first_name'] + +As well as converting a JSON string to a dictionary. You can convert a dictionary to JSON + +For example, given: + +.. code-block:: python + + d = { + 'first_name': 'Guido', + 'second_name': 'Rossum' + } + + import json + print json.dumps(d) + "{'first_name':'Guido','last_name':'Rossum'}" + +It is also possible to import JSON files: + +.. code-block:: python + + import json + with file('path/to/file.json') as json_file: + processed_json = json.load(json_file) + print processsed_json + {u'first_name': u'Guido', u'last_name': u'Rossum'} + +As well as write to them: + +.. code-block:: python + + import json + with file('path/to/file.json', 'w') as json_file: + dict = { + "first_name": "Guido", + "last_name": "Rossum", + "middle_name": "Van" + } + json.dump(dict, json_file) + +simplejson +---------- + +Installation + +.. code-block:: python + + pip install simplejson + +`simplejson `_ is the externally maintained development version of the json library. + +simplejson is updated much more frequently than the Python. Meaning you can get updates much quicker. + +For example, a JSON string like this: + +.. code-block:: python + + "{'first_name':'Guido','last_name':'Rossum'}" + +can be loaded like this: + +.. code-block:: python + + import simplejson + converted_dict = simplejson.loads(json_string) + +you can now use it as a normal dictionary: + +.. code-block:: python + + converted_dict['first_name'] + +As well as converting a json string to dictionarys. You can convert dictionarys to json + +For example, given: + +.. code-block:: python + + import simplejson + + d = { + 'first_name': 'Guido', + 'second_name': 'Rossum' + } + print simplejson.dumps(d) + "{'first_name':'Guido','last_name':'Rossum'}" + + +It is also possible to import JSON files: + +.. code-block:: python + + import simplejson + + with file('path/to/file.json') as json_file: + processed_json = simplejson.load(json_file) + print processsed_json + {u'first_name': u'Guido', u'last_name': u'Rossum'} + +As well as write to them: + +.. code-block:: python + + import simplejson + + with file('path/to/file.json', 'w') as json_file: + dict = { + "first_name": "Guido", + "last_name": "Rossum", + "middle_name": "Van" + } + simplejson.dump(dict, json_file) + From aa951a138ddf03f64dcf8fdab99e16b55bf372af Mon Sep 17 00:00:00 2001 From: Gerard Ryan Date: Mon, 5 Jan 2015 12:08:51 +0000 Subject: [PATCH 02/14] Fix minor type in tests.rst: is -> in --- docs/writing/tests.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/writing/tests.rst b/docs/writing/tests.rst index f416944..f8856d6 100644 --- a/docs/writing/tests.rst +++ b/docs/writing/tests.rst @@ -58,7 +58,7 @@ Some general rules of testing: good set of tests, you or other maintainers will rely largely on the testing suite to fix the problem or modify a given behavior. Therefore the testing code will be read as much as or even more than the running - code. A unit test whose purpose is unclear is not very helpful is this + code. A unit test whose purpose is unclear is not very helpful in this case. - Another use of the testing code is as an introduction to new developers. When From fa307c21413efd115dd883d5c9c92c07f0b01f19 Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 14 Jan 2015 02:31:36 +0100 Subject: [PATCH 03/14] Update cli.rst Fixed Cliff's documentation link, as the ReadTheDocs one is not working. --- docs/scenarios/cli.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/scenarios/cli.rst b/docs/scenarios/cli.rst index 96a1914..c8cdcec 100644 --- a/docs/scenarios/cli.rst +++ b/docs/scenarios/cli.rst @@ -56,7 +56,7 @@ who choose to create a command-line interface because it is quick and simple. Cliff ------ -`Cliff `_ is a framework for +`Cliff `_ is a framework for building command-line programs. It uses setuptools entry points to provide subcommands, output formatters, and other extensions. The framework is meant to be used to create multi-level commands such as subversion and git, where From f5ee4e207a693ff409f83cb608215eb97979fe1e Mon Sep 17 00:00:00 2001 From: Sam Clift Date: Wed, 14 Jan 2015 15:09:50 +0000 Subject: [PATCH 04/14] Improvements to the JSON section Thanks to https://github.com/mplewis --- docs/scenarios/json.rst | 113 ++++++++++++---------------------------- 1 file changed, 33 insertions(+), 80 deletions(-) diff --git a/docs/scenarios/json.rst b/docs/scenarios/json.rst index 3683eec..8a6e492 100644 --- a/docs/scenarios/json.rst +++ b/docs/scenarios/json.rst @@ -1,33 +1,39 @@ -JSON parsing +JSON =========== -json ------ +The `json `_ library can read JSON strings into a Python dictionary or array. It can also serialize Python dictionaries or arrays into JSON strings. -`json `_ is a standard libary which can convert JSON to a Dictionay. +* There are six basic types in JSON: objects, arrays, numbers, strings, booleans, and null. +* The root element of JSON representation is an object, signified by ``{ ... }``. JSON objects are analogous to Python dictionaries: they have keys which correspond to values. +* JSON does not use single quotes. JSON exclusively uses double quotes. Using single quotes in the place of double quotes is invalid JSON syntax. -For example, a JSON string like this: - -.. code-block:: python - - "{'first_name':'Guido','last_name':'Rossum'}" - -can be loaded like this: +Parsing JSON +------------ +The `json `_ libary is imported like this: .. code-block:: python import json + +Take the following string containing JSON data: + +.. code-block:: python + + json_string = '{"first_name": "Guido", "last_name":"Rossum"}' + +It can be manpulated like this: + +.. code-block:: python + converted_dict = json.loads(json_string) -you can now use it as a normal dictionary: +and can now be used as a normal dictionary: .. code-block:: python converted_dict['first_name'] -As well as converting a JSON string to a dictionary. You can convert a dictionary to JSON - -For example, given: +As well as converting a JSON string to a dictionary. You can convert a dictionary to JSON: .. code-block:: python @@ -36,25 +42,24 @@ For example, given: 'second_name': 'Rossum' } - import json - print json.dumps(d) + print(json.dumps(d)) "{'first_name':'Guido','last_name':'Rossum'}" -It is also possible to import JSON files: +We can also load a JSON file by using ``json.load`` instead of ``json.loads``: .. code-block:: python - import json with file('path/to/file.json') as json_file: processed_json = json.load(json_file) - print processsed_json + + print(processsed_json) {u'first_name': u'Guido', u'last_name': u'Rossum'} -As well as write to them: + +Here's an example of writing directly to a file by using ``json.dump`` instead of ``json.dumps``: .. code-block:: python - import json with file('path/to/file.json', 'w') as json_file: dict = { "first_name": "Guido", @@ -65,6 +70,9 @@ As well as write to them: simplejson ---------- +`simplejson `_ is the externally maintained development version of the json library. + +simplejson mimics the json standard library, so you can start using simplejson instead of json by importing it under a different name Installation @@ -72,67 +80,12 @@ Installation pip install simplejson -`simplejson `_ is the externally maintained development version of the json library. - -simplejson is updated much more frequently than the Python. Meaning you can get updates much quicker. - -For example, a JSON string like this: +Usage .. code-block:: python - "{'first_name':'Guido','last_name':'Rossum'}" + import simplejson as json -can be loaded like this: - -.. code-block:: python - - import simplejson - converted_dict = simplejson.loads(json_string) - -you can now use it as a normal dictionary: - -.. code-block:: python - - converted_dict['first_name'] - -As well as converting a json string to dictionarys. You can convert dictionarys to json - -For example, given: - -.. code-block:: python - - import simplejson - - d = { - 'first_name': 'Guido', - 'second_name': 'Rossum' - } - print simplejson.dumps(d) - "{'first_name':'Guido','last_name':'Rossum'}" +simplejson is available so that developers that use an older version of python can use the latest features available in the json lib. -It is also possible to import JSON files: - -.. code-block:: python - - import simplejson - - with file('path/to/file.json') as json_file: - processed_json = simplejson.load(json_file) - print processsed_json - {u'first_name': u'Guido', u'last_name': u'Rossum'} - -As well as write to them: - -.. code-block:: python - - import simplejson - - with file('path/to/file.json', 'w') as json_file: - dict = { - "first_name": "Guido", - "last_name": "Rossum", - "middle_name": "Van" - } - simplejson.dump(dict, json_file) - From 332fdcd6f184bceb7037c1fa0933fe982dc1eae4 Mon Sep 17 00:00:00 2001 From: Sam Clift Date: Wed, 14 Jan 2015 15:19:24 +0000 Subject: [PATCH 05/14] arrays to lists --- docs/scenarios/json.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/scenarios/json.rst b/docs/scenarios/json.rst index 8a6e492..c585731 100644 --- a/docs/scenarios/json.rst +++ b/docs/scenarios/json.rst @@ -1,9 +1,9 @@ JSON =========== -The `json `_ library can read JSON strings into a Python dictionary or array. It can also serialize Python dictionaries or arrays into JSON strings. +The `json `_ library can read JSON strings into a Python dictionary or list. It can also serialize Python dictionaries or lists into JSON strings. -* There are six basic types in JSON: objects, arrays, numbers, strings, booleans, and null. +* There are six basic types in JSON: objects, lists, numbers, strings, booleans, and null. * The root element of JSON representation is an object, signified by ``{ ... }``. JSON objects are analogous to Python dictionaries: they have keys which correspond to values. * JSON does not use single quotes. JSON exclusively uses double quotes. Using single quotes in the place of double quotes is invalid JSON syntax. From 7ff1d0006fa7f3b0204a10af14cc5141dc47fd47 Mon Sep 17 00:00:00 2001 From: Tanya Schlusser Date: Sat, 17 Jan 2015 11:55:26 -0600 Subject: [PATCH 06/14] First attemt at a section on logging. --- docs/writing/logging.rst | 180 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 docs/writing/logging.rst diff --git a/docs/writing/logging.rst b/docs/writing/logging.rst new file mode 100644 index 0000000..e9e8bd1 --- /dev/null +++ b/docs/writing/logging.rst @@ -0,0 +1,180 @@ +Logging +======= + +The :mod:`logging` module has been a part of Python's Standard Library since +version 2.3. It is succinctly described in :pep:`282`. The documentation +is notoriously hard to read, except for the `basic logging tutorial`_, +and often less useful than simply reading the source code. + +Logging serves two purposes: + +- **Diagnostic logging** records events related to the application's + operation. If a user calls in to report an error, for example, the logs + can be searched for context. +- **Audit logging** records events for business analysis. A user's + transactions can be extracted and combined with other user details for + reports or to optimize a business goal. + + +... or Print Statements? +------------------------ + +The only time that ``print`` is a better option than logging is when +the goal is to display a help statement for a command line application. +Other reasons why logging is better than ``print``: + +- The `log record`_, which is created with every logging event, contains + readily available diagnostic information such as the file name, + full path, function, and line number of the logging event. +- Events logged in included modules are automatically accessible via the + root logger + to your application's logging stream, unless you filter them out. +- Logging can be selectively silenced or disabled by using the method + :meth:`logging.Logger.setLevel` or setting the attribute + :attr:`logging.Logger.disabled` to ``True``. + + +Logging in a Library +-------------------- + +Notes for `configuring logging for a library`_ are in the +`basic logging tutorial`_. Because the *user*, not the library, should +dictate what happens when a logging event occurs, One admonition bears +repeating: + +.. note:: + It is strongly advised that you do not add any handlers other than + NullHandler to your library’s loggers. + + +Best practice when instantiating loggers in a library is to only create them +using the ``__name__`` global variable: the :mod:`logging` module creates a +hierarchy of loggers using dot notation, so using ``__name__`` ensures +no name collisions. + +Here is an example of best practice from the `requests source`_ -- place +this in your ``__init__.py`` + +.. code-block:: python + + # Set default logging handler to avoid "No handler found" warnings. + import logging + try: # Python 2.7+ + from logging import NullHandler + except ImportError: + class NullHandler(logging.Handler): + def emit(self, record): + pass + + logging.getLogger(__name__).addHandler(NullHandler()) + + + +Logging in an Application +------------------------- + +The `twelve factor app's `_, an authoritative reference +for good practice in application development, contains a section on +`logging best practice `_. It emphatically +advocates for treating log events as an event stream, and for +sending that event stream to standard output to be handled by the +application environment. Do that. + + +There are at least three ways to configure a logger: + +- using a file (recommended) +- using a dictionary +- using code + +Here is how with a file -- let us say it is named ``logging_config.txt``: + +.. code-block:: none + + [loggers] + keys=root + + [handlers] + keys=stream_handler + + [formatters] + keys=formatter + + [logger_root] + level=DEBUG + handlers=stream_handler + + [handler_stream_handler] + class=StreamHandler + level=DEBUG + formatter=formatter + args=(sys.stderr,) + + [formatter_formatter] + format=%(asctime)s %(name)-12s %(levelname)-8s %(message)s + + +Then use :meth:`logging.config.fileConfig` in the code: + +.. code-block:: python + + import logging + from logging.config import fileConfig + + fileConfig('logging_config.txt') + logger = logging.getLogger() + logger.debug('often makes a very good meal of %s', 'visiting tourists') + + +.. + As of Python 2.7, you can use a dictionary with configuration details: + + .. code-block:: python + + import logging + from logging.config import dictConfig + + logging_config = dict( + version = 1, + formatters = { + 'f': {'format': + '%(asctime)s %(name)-12s %(levelname)-8s %(message)s'} + }, + handlers = { + 'h': {'class': 'logging.StreamHandler', + 'formatter': 'f', + 'level': logging.DEBUG} + }, + loggers = { + root : {'handlers': ['h'], + 'level': logging.DEBUG} + } + ) + + dictConfig(logging_config) + + logger = logging.getLogger() + logger.debug('often makes a very good meal of %s', 'visiting tourists') + + + Or instantiate the logger directly in code: + + .. code-block:: python + + import logging + + logger = logging.getLogger() + handler = logging.StreamHandler() + formatter = logging.Formatter( + '%(asctime)s %(name)-12s %(levelname)-8s %(message)s') + handler.setFormatter(formatter) + logger.addHandler(handler) + logger.setLevel(logging.DEBUG) + + logger.debug('often makes a very good meal of %s', 'visiting tourists') + + +.. _basic logging tutorial: http://docs.python.org/howto/logging.html#logging-basic-tutorial +.. _configuring logging for a library: https://docs.python.org/howto/logging.html#configuring-logging-for-a-library +.. _log record: https://docs.python.org/library/logging.html#logrecord-attributes +.. _requests source: https://github.com/kennethreitz/requests From 95ecb66c9631960624687f1c77d341d629113493 Mon Sep 17 00:00:00 2001 From: Tanya Schlusser Date: Sat, 17 Jan 2015 11:56:16 -0600 Subject: [PATCH 07/14] Added the logging section after the testing section in the Writing page --- docs/contents.rst.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/contents.rst.inc b/docs/contents.rst.inc index cc38532..b312ee3 100644 --- a/docs/contents.rst.inc +++ b/docs/contents.rst.inc @@ -32,6 +32,7 @@ This part of the guide focuses on best practices for writing Python code. writing/reading writing/documentation writing/tests + writing/logging writing/gotchas writing/license From 7c37ec8396b2487cc1dc38b86fa78f9d361163e5 Mon Sep 17 00:00:00 2001 From: Tanya Schlusser Date: Sat, 17 Jan 2015 20:59:53 -0600 Subject: [PATCH 08/14] Modified the new writing/logging.rst according to comments on the initial pull request --- docs/writing/logging.rst | 121 +++++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 55 deletions(-) diff --git a/docs/writing/logging.rst b/docs/writing/logging.rst index e9e8bd1..e138ad9 100644 --- a/docs/writing/logging.rst +++ b/docs/writing/logging.rst @@ -3,8 +3,7 @@ Logging The :mod:`logging` module has been a part of Python's Standard Library since version 2.3. It is succinctly described in :pep:`282`. The documentation -is notoriously hard to read, except for the `basic logging tutorial`_, -and often less useful than simply reading the source code. +is notoriously hard to read, except for the `basic logging tutorial`_. Logging serves two purposes: @@ -16,8 +15,8 @@ Logging serves two purposes: reports or to optimize a business goal. -... or Print Statements? ------------------------- +... or Print? +------------- The only time that ``print`` is a better option than logging is when the goal is to display a help statement for a command line application. @@ -73,23 +72,28 @@ this in your ``__init__.py`` Logging in an Application ------------------------- -The `twelve factor app's `_, an authoritative reference +The `twelve factor app `_, an authoritative reference for good practice in application development, contains a section on `logging best practice `_. It emphatically advocates for treating log events as an event stream, and for sending that event stream to standard output to be handled by the -application environment. Do that. +application environment. There are at least three ways to configure a logger: -- using a file (recommended) +- using a file - using a dictionary - using code -Here is how with a file -- let us say it is named ``logging_config.txt``: +Example Configuration via an INI File +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. code-block:: none +Let us say the file is named ``logging_config.ini``. +More details for the file format are in the `logging configuration`_ +section of the `logging tutorial`_. + +.. code-block:: ini [loggers] keys=root @@ -126,55 +130,62 @@ Then use :meth:`logging.config.fileConfig` in the code: logger.debug('often makes a very good meal of %s', 'visiting tourists') -.. - As of Python 2.7, you can use a dictionary with configuration details: - - .. code-block:: python - - import logging - from logging.config import dictConfig - - logging_config = dict( - version = 1, - formatters = { - 'f': {'format': - '%(asctime)s %(name)-12s %(levelname)-8s %(message)s'} - }, - handlers = { - 'h': {'class': 'logging.StreamHandler', - 'formatter': 'f', - 'level': logging.DEBUG} - }, - loggers = { - root : {'handlers': ['h'], - 'level': logging.DEBUG} - } - ) - - dictConfig(logging_config) - - logger = logging.getLogger() - logger.debug('often makes a very good meal of %s', 'visiting tourists') - - - Or instantiate the logger directly in code: - - .. code-block:: python - - import logging - - logger = logging.getLogger() - handler = logging.StreamHandler() - formatter = logging.Formatter( - '%(asctime)s %(name)-12s %(levelname)-8s %(message)s') - handler.setFormatter(formatter) - logger.addHandler(handler) - logger.setLevel(logging.DEBUG) - - logger.debug('often makes a very good meal of %s', 'visiting tourists') +Example Configuration via a Dictionary +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As of Python 2.7, you can use a dictionary with configuration details. +:pep:`319` contains a list of the mandatory and optional elements in +the configuration dictionary. + +.. code-block:: python + + import logging + from logging.config import dictConfig + + logging_config = dict( + version = 1, + formatters = { + 'f': {'format': + '%(asctime)s %(name)-12s %(levelname)-8s %(message)s'} + }, + handlers = { + 'h': {'class': 'logging.StreamHandler', + 'formatter': 'f', + 'level': logging.DEBUG} + }, + loggers = { + root : {'handlers': ['h'], + 'level': logging.DEBUG} + } + ) + + dictConfig(logging_config) + + logger = logging.getLogger() + logger.debug('often makes a very good meal of %s', 'visiting tourists') + + +Example Configuration Directly in Code +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + import logging + + logger = logging.getLogger() + handler = logging.StreamHandler() + formatter = logging.Formatter( + '%(asctime)s %(name)-12s %(levelname)-8s %(message)s') + handler.setFormatter(formatter) + logger.addHandler(handler) + logger.setLevel(logging.DEBUG) + + logger.debug('often makes a very good meal of %s', 'visiting tourists') .. _basic logging tutorial: http://docs.python.org/howto/logging.html#logging-basic-tutorial +.. _logging configuration: https://docs.python.org/howto/logging.html#configuring-logging +.. _logging tutorial: http://docs.python.org/howto/logging.html .. _configuring logging for a library: https://docs.python.org/howto/logging.html#configuring-logging-for-a-library .. _log record: https://docs.python.org/library/logging.html#logrecord-attributes .. _requests source: https://github.com/kennethreitz/requests From 1cfb637cb1babcc7f0ecb1d48b6f3bb4d093e3a5 Mon Sep 17 00:00:00 2001 From: Tanya Schlusser Date: Sat, 17 Jan 2015 21:05:56 -0600 Subject: [PATCH 09/14] Removed a stray capitalization and improved the grammar in the 'print' vs 'logging' section --- docs/writing/logging.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/writing/logging.rst b/docs/writing/logging.rst index e138ad9..7faa553 100644 --- a/docs/writing/logging.rst +++ b/docs/writing/logging.rst @@ -28,8 +28,8 @@ Other reasons why logging is better than ``print``: - Events logged in included modules are automatically accessible via the root logger to your application's logging stream, unless you filter them out. -- Logging can be selectively silenced or disabled by using the method - :meth:`logging.Logger.setLevel` or setting the attribute +- Logging can be selectively silenced by using the method + :meth:`logging.Logger.setLevel` or disabled by setting the attribute :attr:`logging.Logger.disabled` to ``True``. @@ -37,8 +37,8 @@ Logging in a Library -------------------- Notes for `configuring logging for a library`_ are in the -`basic logging tutorial`_. Because the *user*, not the library, should -dictate what happens when a logging event occurs, One admonition bears +`logging tutorial`_. Because the *user*, not the library, should +dictate what happens when a logging event occurs, one admonition bears repeating: .. note:: @@ -86,6 +86,7 @@ There are at least three ways to configure a logger: - using a dictionary - using code + Example Configuration via an INI File ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 0c1551ae85940d9f75a79865356da02a72abad7b Mon Sep 17 00:00:00 2001 From: Tanya Schlusser Date: Sat, 17 Jan 2015 21:09:52 -0600 Subject: [PATCH 10/14] Added pro / con bullets to the list of ways to configure a logger --- docs/writing/logging.rst | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/writing/logging.rst b/docs/writing/logging.rst index 7faa553..0cee15d 100644 --- a/docs/writing/logging.rst +++ b/docs/writing/logging.rst @@ -82,9 +82,20 @@ application environment. There are at least three ways to configure a logger: -- using a file -- using a dictionary -- using code +- Using an INI-formatted file: + - *Pro* -- possible to update configuration while running + using the function :func:`logging.config.listen` to listen + on a socket. + - *Con* -- less control (*e.g.* custom subclassed filters or loggers) + than possible when configuring a logger in code. +- Using a dictionary or a JSON-formatted file: + - *Pro* -- in addition to updating while running, it is possible to + load from a file using the :mod:`json` module, in the standard + library since Python 2.6. + - *Con* -- less control than when configuring a logger in code. +- Using code: + - *Pro* -- complete control over the configuration. + - *Con* -- modifications require a change to source code. Example Configuration via an INI File From df7a22568bc4e944fd37a41ebf1f2740ff54976d Mon Sep 17 00:00:00 2001 From: Tanya Schlusser Date: Sat, 17 Jan 2015 21:43:22 -0600 Subject: [PATCH 11/14] Italic pro/con to bold, and '--' to colon after the pro/con --- docs/writing/logging.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/writing/logging.rst b/docs/writing/logging.rst index 0cee15d..70e20de 100644 --- a/docs/writing/logging.rst +++ b/docs/writing/logging.rst @@ -83,19 +83,19 @@ application environment. There are at least three ways to configure a logger: - Using an INI-formatted file: - - *Pro* -- possible to update configuration while running + - **Pro**: possible to update configuration while running using the function :func:`logging.config.listen` to listen on a socket. - - *Con* -- less control (*e.g.* custom subclassed filters or loggers) + - **Con**: less control (*e.g.* custom subclassed filters or loggers) than possible when configuring a logger in code. - Using a dictionary or a JSON-formatted file: - - *Pro* -- in addition to updating while running, it is possible to + - **Pro**: in addition to updating while running, it is possible to load from a file using the :mod:`json` module, in the standard library since Python 2.6. - - *Con* -- less control than when configuring a logger in code. + - **Con**: less control than when configuring a logger in code. - Using code: - - *Pro* -- complete control over the configuration. - - *Con* -- modifications require a change to source code. + - **Pro**: complete control over the configuration. + - **Con**: modifications require a change to source code. Example Configuration via an INI File From 37ed5fc40a75b60d2d3cb9f4e8f11ce6a7f32d96 Mon Sep 17 00:00:00 2001 From: Sam Clift Date: Sun, 18 Jan 2015 14:22:30 +0000 Subject: [PATCH 12/14] update based on PR feedback --- docs/scenarios/json.rst | 59 +++++++---------------------------------- 1 file changed, 10 insertions(+), 49 deletions(-) diff --git a/docs/scenarios/json.rst b/docs/scenarios/json.rst index c585731..29d87c4 100644 --- a/docs/scenarios/json.rst +++ b/docs/scenarios/json.rst @@ -1,15 +1,12 @@ JSON -=========== +==== -The `json `_ library can read JSON strings into a Python dictionary or list. It can also serialize Python dictionaries or lists into JSON strings. - -* There are six basic types in JSON: objects, lists, numbers, strings, booleans, and null. -* The root element of JSON representation is an object, signified by ``{ ... }``. JSON objects are analogous to Python dictionaries: they have keys which correspond to values. -* JSON does not use single quotes. JSON exclusively uses double quotes. Using single quotes in the place of double quotes is invalid JSON syntax. +The `json `_ library can parse JSON from strings or files. When parsing, the library converts the JSON into a Python dictionary or list. It can also parse Python dictionaries or lists into JSON strings. Parsing JSON ------------ -The `json `_ libary is imported like this: + +The json libary is imported like this: .. code-block:: python @@ -21,7 +18,7 @@ Take the following string containing JSON data: json_string = '{"first_name": "Guido", "last_name":"Rossum"}' -It can be manpulated like this: +It can be parsed like this: .. code-block:: python @@ -31,9 +28,10 @@ and can now be used as a normal dictionary: .. code-block:: python - converted_dict['first_name'] + print(converted_dict['first_name']) + "Guido" -As well as converting a JSON string to a dictionary. You can convert a dictionary to JSON: +You can also convert a dictionary to JSON: .. code-block:: python @@ -45,47 +43,10 @@ As well as converting a JSON string to a dictionary. You can convert a dictionar print(json.dumps(d)) "{'first_name':'Guido','last_name':'Rossum'}" -We can also load a JSON file by using ``json.load`` instead of ``json.loads``: - -.. code-block:: python - - with file('path/to/file.json') as json_file: - processed_json = json.load(json_file) - - print(processsed_json) - {u'first_name': u'Guido', u'last_name': u'Rossum'} - - -Here's an example of writing directly to a file by using ``json.dump`` instead of ``json.dumps``: - -.. code-block:: python - - with file('path/to/file.json', 'w') as json_file: - dict = { - "first_name": "Guido", - "last_name": "Rossum", - "middle_name": "Van" - } - json.dump(dict, json_file) simplejson ---------- + `simplejson `_ is the externally maintained development version of the json library. -simplejson mimics the json standard library, so you can start using simplejson instead of json by importing it under a different name - -Installation - -.. code-block:: python - - pip install simplejson - -Usage - -.. code-block:: python - - import simplejson as json - -simplejson is available so that developers that use an older version of python can use the latest features available in the json lib. - - +simplejson mimics the json standard library, it is available so that developers that use an older version of python can use the latest features available in the json lib. From f1e196a73f3cef46af504b4b5705a60327df6949 Mon Sep 17 00:00:00 2001 From: Ian Cordasco Date: Sun, 18 Jan 2015 09:58:33 -0600 Subject: [PATCH 13/14] Commit last few necessary edits These were all previously ignored in the last two pull requests. --- docs/scenarios/json.rst | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/docs/scenarios/json.rst b/docs/scenarios/json.rst index 29d87c4..a3f7ffa 100644 --- a/docs/scenarios/json.rst +++ b/docs/scenarios/json.rst @@ -6,12 +6,6 @@ The `json `_ library can parse JSON Parsing JSON ------------ -The json libary is imported like this: - -.. code-block:: python - - import json - Take the following string containing JSON data: .. code-block:: python @@ -22,26 +16,28 @@ It can be parsed like this: .. code-block:: python - converted_dict = json.loads(json_string) + import json + parsed_json = json.loads(json_string) and can now be used as a normal dictionary: .. code-block:: python - print(converted_dict['first_name']) + print(parsed_json['first_name']) "Guido" -You can also convert a dictionary to JSON: +You can also convert a the following to JSON: .. code-block:: python d = { 'first_name': 'Guido', - 'second_name': 'Rossum' + 'second_name': 'Rossum', + 'titles': ['BDFL', 'Developer'], } print(json.dumps(d)) - "{'first_name':'Guido','last_name':'Rossum'}" + '{"first_name": "Guido", "last_name": "Rossum", "titles": ["BDFL", "Developer"]}' simplejson From 0f797099e1c99133d1d4db01c8aee9e4b707e0cb Mon Sep 17 00:00:00 2001 From: Ian Cordasco Date: Sun, 18 Jan 2015 09:59:38 -0600 Subject: [PATCH 14/14] Change logging_config extension to ini --- docs/writing/logging.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/writing/logging.rst b/docs/writing/logging.rst index 70e20de..4a36edb 100644 --- a/docs/writing/logging.rst +++ b/docs/writing/logging.rst @@ -137,7 +137,7 @@ Then use :meth:`logging.config.fileConfig` in the code: import logging from logging.config import fileConfig - fileConfig('logging_config.txt') + fileConfig('logging_config.ini') logger = logging.getLogger() logger.debug('often makes a very good meal of %s', 'visiting tourists')