Skip to content

Commit c2ac173

Browse files
committed
docs
1 parent b819f70 commit c2ac173

File tree

2 files changed

+74
-68
lines changed

2 files changed

+74
-68
lines changed

doc/source/examples/tools_example.rst

Lines changed: 48 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ Automatically Capture User Info
1313
One task we would like to do is to capture and propagate useful metadata that describes the diffraction data.
1414
Some is essential such as wavelength and radiation type. Other metadata is useful such as information about the
1515
sample, co-workers and so on. However, one of the most important bits of information is the name of the data owner.
16-
For example, in ``DiffractionObjects`` this is stored in the ``metadata`` dictionary as ``username``, ``user_email``,
17-
and ``user_orcid``.
16+
For example, in ``DiffractionObjects`` this is stored in the ``metadata`` dictionary as ``owner_name``, ``owner_email``,
17+
and ``owner_orcid``.
1818

1919
To reduce experimenter overhead when collecting this information, we have developed an infrastructure that helps
20-
to capture this information automatically when you are using `DiffractionObjects` and other diffpy tools.
20+
to capture this information automatically when you are using ``DiffractionObjects`` and other diffpy tools.
2121
You may also reuse this infrastructure for your own projects using tools in this tutorial.
2222

2323
This example will demonstrate how ``diffpy.utils`` allows us to conveniently load and manage user and package information.
@@ -28,8 +28,9 @@ Load user info into your program
2828

2929
To use this functionality in your own code make use of the ``get_user_info`` function in
3030
``diffpy.utils.tools`` which will search for information about the user, parse it, and return
31-
it in a dictionary object e.g. if the user is "Jane Doe" with email "janedoe@gmail.com" and the
32-
function can find the information, if you type this
31+
it in a dictionary object e.g. if the user is "Jane Doe" with email "janedoe@gmail.com" and ORCID
32+
"0000-0000-0000-0000", and if the
33+
function can find the information (more on this below), if you type this
3334

3435
.. code-block:: python
3536
@@ -40,16 +41,17 @@ The function will return
4041

4142
.. code-block:: python
4243
43-
{"email": "janedoe@email.com", "username": "Jane Doe"}
44+
{"owner_email": "janedoe@email.com", "owner_name": "Jane Doe", "owner_orcid": "0000-0000-0000-0000"}
4445
4546
4647
Where does ``get_user_info()`` get the user information from?
4748
-------------------------------------------------------------
4849

4950
The function will first attempt to load the information from configuration files with the name ``diffpyconfig.json``
5051
on your hard-drive.
51-
It looks first for the file in the current working directory. If it cannot find it there it will look
52-
user's home, i.e., login, directory. To find this directory, open a terminal and a unix or mac system type ::
52+
It looks for files in the current working directory and in the computer-user's home (i.e., login) directory.
53+
For example, it might be in C:/Users/yourname`` or something like that, but to find this directory, open
54+
a terminal and a unix or mac system type ::
5355

5456
cd ~
5557
pwd
@@ -58,67 +60,55 @@ Or type ``Echo $HOME``. On a Windows computer ::
5860

5961
echo %USERPROFILE%"
6062

63+
It is also possible to override the values in the config files at run-time by passing values directly into the
64+
function according to ``get_user_info``, for example,
65+
``get_user_info(owner_name="Janet Doe", owner_email="janetdoe@email.com", owner_orcid="1111-1111-1111-1111")``.
66+
The information to pass into ``get_user_info`` could be entered by a user through a command-line interface
67+
or into a gui.
68+
6169
What if no config files exist yet?
6270
-----------------------------------
6371

64-
If no configuration files can be found, the function attempts to create one in the user's home
65-
directory. The function will pause execution and ask for a user-response to enter the information.
66-
It will then write the config file in the user's home directory.
67-
68-
In this way, the next, and subsequent times the program is run, it will no longer have to prompt the user
69-
as it will successfully find the new config file.
70-
71-
Getting user data with no config files and with no interruption of execution
72-
----------------------------------------------------------------------------
72+
If no configuration files can be found, they can be created using a text editor, or by using a diffpy tool
73+
called ``check_and_build_global_config()`` which, if no global config file can be found, prompts the user for the
74+
information then writes the config file in the user's home directory.
7375

74-
If you would like get run ``get_user_data()`` but without execution interruption even if it cannot find
75-
an input file, type
76+
When building an application where you want to capture data-owner information, we recommend you execute
77+
``check_and_build_global_config()`` first followed by ``get_user_info`` in your app workflow. E.g.,
7678

7779
.. code-block:: python
78-
79-
user_data = get_user_data(skip_config_creation=True)
80-
81-
Passing user information directly to ``get_user_data()``
82-
--------------------------------------------------------
83-
84-
It can be passed user information which fully or partially overrides looking in config files
85-
For example, in this way it would be possible to pass in information
86-
that is entered through a gui or command line interface. E.g.,
87-
88-
.. code-block:: python
89-
90-
new_user_info = get_user_info({"username": "new_username", "email": "new@example.com"})
91-
92-
This returns ``{"username": "new_username", "email": "new@example.com"}`` (and so, effectively, does nothing)
93-
However, You can update only the username or email individually, for example
94-
95-
.. code-block:: python
96-
97-
new_user_info = get_user_info({"username": new_username})
98-
99-
will return ``{"username": "new_username", "email": "janedoe@gmail.com"}``
100-
if it found ``janedoe@gmail.com`` as the email in the config file.
101-
Similarly, you can update only the email in the returned dictionary,
102-
103-
.. code-block:: python
104-
105-
new_user_info = get_user_info({"email": new@email.com})
106-
107-
which will return ``{"username": "Jane Doe", "email": "new@email.com"}``
108-
if it found ``Jane Doe`` as the user in the config file.
109-
110-
I entered the wrong information in my config file so it always loads incorrect information
111-
------------------------------------------------------------------------------------------
112-
113-
You can use of the above methods to temporarily override the incorrect information in your
114-
global config file. However, it is easy to fix this simply by editing that file using a text
80+
from diffpy.utils.tools import check_and_build_global_config, get_user_info
81+
from datetime import datetime
82+
import json
83+
84+
def my_cool_data_enhancer_app_main(data, filepath):
85+
check_and_build_global_config()
86+
metadata_enhanced_data = get_user_info()
87+
metadata_enhanced_data.update({"creation_time": datetime.now(),
88+
"data": data})
89+
with open(filepath, "w") as f:
90+
json.dump(metadata_enhanced_data, f)
91+
92+
``check_and_build_global_config()`` only
93+
interrupts execution if it can't find a valid config file, and so if the user enters valid information
94+
it will only run once. However, if you want to bypass this behavior,
95+
``check_and_build_global_config()`` takes an optional boolean ``skip_config_creation`` parameter that
96+
could be set to ``True`` at runtime to override the config creation.
97+
98+
I entered the wrong information in my config file so it always loads incorrect information, how do I fix that?
99+
--------------------------------------------------------------------------------------------------------------
100+
101+
It is easy to fix this simply by deleting the global and/or local config files, which will allow
102+
you to re-enter the information during the ``check_and_build_global_config()`` initialization
103+
workflow. You can also simply editi the ``diffpyconfig.json`` file directly using a text
115104
editor.
116105

117106
Locate the file ``diffpyconfig.json``, in your home directory and open it in an editor ::
118107

119108
{
120-
"username": "John Doe",
121-
"email": "john.doe@example.com"
109+
"owner_name": "John Doe",
110+
"owner_email": "john.doe@example.com"
111+
"owner_orcid": "0000-0000-4321-1234"
122112
}
123113

124114
Then you can edit the username and email as needed, make sure to save your edits.

src/diffpy/utils/tools.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,22 +92,38 @@ def _create_global_config(args):
9292

9393
def get_user_info(owner_name=None, owner_email=None, owner_orcid=None):
9494
"""
95-
Get username, email and orcid configuration.
96-
97-
First attempts to load config file from global and local paths.
98-
If neither exists, creates a global config file.
99-
It prioritizes values from args, then local, then global.
100-
Removes invalid global config file if creation is needed, replacing it with empty username and email.
95+
Get name, email and orcid of the owner/user from various sources and return it as a metadata dictionary
96+
97+
The function looks for the information in json format configuration files with the name 'diffpyconfig.json'.
98+
These can be in the user's home directory and in the current working directory. The information in the
99+
config files are combined, with the local config overriding the home-directory one. Values for
100+
owner_name, owner_email, and owner_orcid may be passed in to the function and these override the values
101+
in the config files.
102+
103+
A template for the config file is below. Create a text file called 'diffpyconfig.json' in your home directory
104+
and copy-paste the template into it, editing it with your real information.
105+
{
106+
"owner_name": "<your name as you would like it stored with your data>>",
107+
"owner_email": "<your_associated_email>>@email.com",
108+
"owner_orcid": "<your_associated_orcid if you would like this stored with your data>>"
109+
}
110+
You may also store any other gloabl-level information that you would like associated with your
111+
diffraction data in this file
101112
102113
Parameters
103114
----------
104-
args argparse.Namespace
105-
The arguments from the parser, default is None.
115+
owner_name: string, optional, default is the value stored in the global or local config file.
116+
The name of the user who will show as owner in the metadata that is stored with the data
117+
owner_email: string, optional, default is the value stored in the global or local config file.
118+
The email of the user/owner
119+
owner_name: string, optional, default is the value stored in the global or local config file.
120+
The ORCID id of the user/owner
106121
107122
Returns
108123
-------
109-
dict or None:
110-
The dictionary containing username and email with corresponding values.
124+
dict:
125+
The dictionary containing username, email and orcid of the user/owner, and any other information
126+
stored in the global or local config files.
111127
112128
"""
113129
runtime_info = {"owner_name": owner_name, "owner_email": owner_email, "owner_orcid": owner_orcid}

0 commit comments

Comments
 (0)