caltechdata-api 1.9.1__tar.gz → 1.10.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/PKG-INFO +14 -10
  2. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/README.md +5 -2
  3. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api/__init__.py +2 -1
  4. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api/caltechdata_edit.py +8 -4
  5. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api/cli.py +140 -35
  6. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api/customize_schema.py +26 -27
  7. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api.egg-info/PKG-INFO +14 -10
  8. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api.egg-info/SOURCES.txt +2 -0
  9. caltechdata_api-1.10.1/pyproject.toml +3 -0
  10. caltechdata_api-1.10.1/setup.cfg +54 -0
  11. caltechdata_api-1.10.1/setup.py +3 -0
  12. caltechdata_api-1.9.1/setup.cfg +0 -4
  13. caltechdata_api-1.9.1/setup.py +0 -179
  14. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/LICENSE +0 -0
  15. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api/caltechdata_write.py +0 -0
  16. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api/download_file.py +0 -0
  17. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api/get_files.py +0 -0
  18. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api/get_metadata.py +0 -0
  19. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api/md_to_json.py +0 -0
  20. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api/utils.py +0 -0
  21. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api.egg-info/dependency_links.txt +0 -0
  22. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api.egg-info/entry_points.txt +0 -0
  23. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api.egg-info/requires.txt +0 -0
  24. {caltechdata_api-1.9.1 → caltechdata_api-1.10.1}/caltechdata_api.egg-info/top_level.txt +0 -0
@@ -1,23 +1,24 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: caltechdata_api
3
- Version: 1.9.1
3
+ Version: 1.10.1
4
4
  Summary: Python wrapper for CaltechDATA API.
5
5
  Home-page: https://github.com/caltechlibrary/caltechdata_api
6
- Author: Thomas E Morrell, Bhattarai Rohan , Won Elizabeth
7
- Author-email: tmorrell@caltech.edu, ,
8
- License: https://data.caltech.edu/license
6
+ Author: Thomas E Morrell, Rohan Bhattarai, Elizabeth Won, Alexander A Abakah, Kshemaahna Nagi
7
+ Author-email: tmorrell@caltech.edu, aabakah@caltech.edu, knagi@caltech.edu
8
+ License: MIT
9
9
  Platform: UNKNOWN
10
- Classifier: License :: OSI Approved :: BSD License
11
- Classifier: Programming Language :: Python
10
+ Classifier: License :: OSI Approved :: MIT License
12
11
  Classifier: Programming Language :: Python :: 3
13
12
  Classifier: Programming Language :: Python :: 3.7
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
14
16
  Classifier: Programming Language :: Python :: Implementation :: CPython
15
- Classifier: Programming Language :: Python :: Implementation :: PyPy
17
+ Classifier: Operating System :: OS Independent
16
18
  Requires-Python: >=3.6.0
17
19
  Description-Content-Type: text/markdown
18
20
  License-File: LICENSE
19
21
 
20
-
21
22
  # CaltechDATA API Python Library
22
23
 
23
24
  [![DOI](https://img.shields.io/badge/dynamic/json.svg?label=DOI&query=$.pids.doi.identifier&uri=https://data.caltech.edu/api/records/wfjr5-kw507/versions/latest)](https://data.caltech.edu/records/wfjr5-kw507/latest)
@@ -49,7 +50,7 @@ pip install caltechdata_api
49
50
 
50
51
  There are some example python scripts in the GitHub repository.
51
52
 
52
- ###Create a record:
53
+ ### Create a record:
53
54
 
54
55
  ```shell
55
56
  python write.py example.json -fnames logo.gif
@@ -59,7 +60,7 @@ python write.py example.json -fnames logo.gif
59
60
  the end of a url to visit the record (e.g.
60
61
  https://data.caltechlibrary.dev/records/pbkn6-m9y63)
61
62
 
62
- ###Edit a record
63
+ ### Edit a record
63
64
  Make changes to the example.json file to see a change)
64
65
  ```
65
66
  python edit.py example.json -id pbkn6-m9y63
@@ -97,5 +98,8 @@ This returns the custom DOI of the record if it is successful.
97
98
  Only test your application on the test repository (`data.caltechlibrary.dev`). Testing the API on the public
98
99
  repository will generate junk records that are annoying to delete.
99
100
 
101
+ ## Using the Command Line Interface
102
+
103
+ If you would like to interact with the CaltechDATA API using the Command line Interface (CLI), please [see the detailed documentation](https://caltechlibrary.github.io/caltechdata_api/caltechdata_api/cli-documentation-for-users).
100
104
 
101
105
 
@@ -29,7 +29,7 @@ pip install caltechdata_api
29
29
 
30
30
  There are some example python scripts in the GitHub repository.
31
31
 
32
- ###Create a record:
32
+ ### Create a record:
33
33
 
34
34
  ```shell
35
35
  python write.py example.json -fnames logo.gif
@@ -39,7 +39,7 @@ python write.py example.json -fnames logo.gif
39
39
  the end of a url to visit the record (e.g.
40
40
  https://data.caltechlibrary.dev/records/pbkn6-m9y63)
41
41
 
42
- ###Edit a record
42
+ ### Edit a record
43
43
  Make changes to the example.json file to see a change)
44
44
  ```
45
45
  python edit.py example.json -id pbkn6-m9y63
@@ -77,3 +77,6 @@ This returns the custom DOI of the record if it is successful.
77
77
  Only test your application on the test repository (`data.caltechlibrary.dev`). Testing the API on the public
78
78
  repository will generate junk records that are annoying to delete.
79
79
 
80
+ ## Using the Command Line Interface
81
+
82
+ If you would like to interact with the CaltechDATA API using the Command line Interface (CLI), please [see the detailed documentation](https://caltechlibrary.github.io/caltechdata_api/caltechdata_api/cli-documentation-for-users).
@@ -9,7 +9,8 @@ from .caltechdata_edit import (
9
9
  caltechdata_unembargo,
10
10
  caltechdata_accept,
11
11
  )
12
- from .customize_schema import customize_schema
12
+ from .customize_schema import customize_schema, validate_metadata
13
13
  from .get_metadata import get_metadata
14
14
  from .download_file import download_file, download_url
15
15
  from .utils import humanbytes
16
+ from .md_to_json import parse_readme_to_json
@@ -66,6 +66,7 @@ def caltechdata_edit(
66
66
  default_preview=None,
67
67
  authors=False,
68
68
  keepfiles=False,
69
+ return_id=False,
69
70
  ):
70
71
  # Make a copy of the metadata to make sure our local changes don't leak
71
72
  metadata = copy.deepcopy(metadata)
@@ -299,10 +300,13 @@ def caltechdata_edit(
299
300
  result = requests.post(publish_link, headers=headers)
300
301
  if result.status_code != 202:
301
302
  raise Exception(result.text)
302
- pids = result.json()["pids"]
303
- if "doi" in pids:
304
- return pids["doi"]["identifier"]
303
+ if return_id:
304
+ return result.json()["id"]
305
305
  else:
306
- return pids["oai"]["identifier"]
306
+ pids = result.json()["pids"]
307
+ if "doi" in pids:
308
+ return pids["doi"]["identifier"]
309
+ else:
310
+ return pids["oai"]["identifier"]
307
311
  else:
308
312
  return idv
@@ -1,8 +1,7 @@
1
1
  import argparse
2
2
  import requests
3
3
  import s3fs
4
- from caltechdata_api import caltechdata_write, caltechdata_edit
5
- from md_to_json import parse_readme_to_json
4
+ from caltechdata_api import caltechdata_write, caltechdata_edit, parse_readme_to_json
6
5
  import json
7
6
  import os
8
7
  from cryptography.fernet import Fernet
@@ -59,11 +58,17 @@ def decrypt_token(encrypted_token, key):
59
58
  return f.decrypt(encrypted_token).decode()
60
59
 
61
60
 
62
- # Function to get or set token with support for test system
61
+ # Function to get or set token with support for test system.
63
62
  def get_or_set_token(production=True):
63
+ # First check for environment variable
64
+ env_token = os.environ.get("CALTECHDATA_TOKEN")
65
+ if env_token:
66
+ print("Using token from environment variable")
67
+ return env_token
68
+
64
69
  key = load_or_generate_key()
65
70
 
66
- # Use different token files for production and test environments
71
+ # Use different token files for production and test environment.
67
72
  token_filename = "token.txt" if production else "token_test.txt"
68
73
  token_file = os.path.join(caltechdata_directory, token_filename)
69
74
 
@@ -94,6 +99,16 @@ def get_or_set_token(production=True):
94
99
  print("Tokens do not match. Please try again.")
95
100
 
96
101
 
102
+ # Delete the saved token file.
103
+ def delete_saved_token():
104
+ token_file = os.path.join(caltechdata_directory, "token.txt")
105
+ if os.path.exists(token_file):
106
+ os.remove(token_file)
107
+ print("Token deleted successfully.")
108
+ else:
109
+ print("No token found to delete.")
110
+
111
+
97
112
  def welcome_message():
98
113
  print("Welcome to CaltechDATA CLI")
99
114
 
@@ -181,6 +196,61 @@ def get_funding_details():
181
196
  }
182
197
 
183
198
 
199
+ # Add profile handling functions
200
+ def save_profile():
201
+ profile_file = os.path.join(caltechdata_directory, "profile.json")
202
+
203
+ # Get ORCID
204
+ while True:
205
+ orcid = get_user_input("Enter your ORCID identifier: ")
206
+ orcid = normalize_orcid(orcid)
207
+ family_name, given_name = get_names(orcid)
208
+ if family_name is not None and given_name is not None:
209
+ break
210
+ retry = input("Do you want to try again? (y/n): ")
211
+ if retry.lower() != "y":
212
+ return None
213
+
214
+ # Get funding details
215
+ funding_references = []
216
+ num_funding_entries = get_funding_entries()
217
+ for _ in range(num_funding_entries):
218
+ funding_references.append(get_funding_details())
219
+
220
+ profile_data = {
221
+ "orcid": orcid,
222
+ "family_name": family_name,
223
+ "given_name": given_name,
224
+ "funding_references": funding_references,
225
+ }
226
+
227
+ with open(profile_file, "w") as f:
228
+ json.dump(profile_data, f, indent=2)
229
+
230
+ print("Profile saved successfully!")
231
+ return profile_data
232
+
233
+
234
+ def load_profile():
235
+ profile_file = os.path.join(caltechdata_directory, "profile.json")
236
+ try:
237
+ with open(profile_file, "r") as f:
238
+ return json.load(f)
239
+ except FileNotFoundError:
240
+ return None
241
+
242
+
243
+ def get_or_create_profile():
244
+ profile = load_profile()
245
+ if profile:
246
+ use_saved = input("Use saved profile? (y/n): ").lower()
247
+ if use_saved == "y":
248
+ return profile
249
+
250
+ print("Creating new profile...")
251
+ return save_profile()
252
+
253
+
184
254
  def parse_arguments():
185
255
  welcome_message()
186
256
  args = {}
@@ -217,23 +287,17 @@ def parse_arguments():
217
287
  break
218
288
  else:
219
289
  print("Invalid input. Please enter a number between 1 and 8.")
290
+ # Load or create profile
291
+ profile = get_or_create_profile()
292
+ if profile:
293
+ args["orcid"] = profile["orcid"]
294
+ args["family_name"] = profile["family_name"]
295
+ args["given_name"] = profile["given_name"]
296
+ args["fundingReferences"] = profile["funding_references"]
297
+ else:
298
+ print("Failed to load or create profile. Exiting.")
299
+ return None
220
300
 
221
- while True:
222
- orcid = get_user_input("Enter your ORCID identifier: ")
223
- family_name, given_name = get_names(orcid)
224
- if family_name is not None and given_name is not None:
225
- args["orcid"] = orcid
226
- break # Break out of the loop if names are successfully retrieved
227
- retry = input("Do you want to try again? (y/n): ")
228
- if retry.lower() != "y":
229
- print("Exiting program.")
230
- return
231
- # Optional arguments
232
- num_funding_entries = get_funding_entries()
233
- funding_references = []
234
- for _ in range(num_funding_entries):
235
- funding_references.append(get_funding_details())
236
- args["fundingReferences"] = funding_references
237
301
  return args
238
302
 
239
303
 
@@ -296,6 +360,7 @@ def upload_supporting_file(record_id=None):
296
360
  filepaths = []
297
361
  file_link = ""
298
362
  file_links = []
363
+ idx = 0
299
364
  while True:
300
365
  choice = get_user_input(
301
366
  "Do you want to upload or link data files? (upload/link/n): "
@@ -338,14 +403,28 @@ def upload_supporting_file(record_id=None):
338
403
  files = [
339
404
  f for f in os.listdir() if not f.endswith(".json") and os.path.isfile(f)
340
405
  ]
341
- print("\n".join(files))
406
+ idx += 1
407
+ print((f"{idx}/ \n").join(files))
342
408
  while True:
343
409
  filename = get_user_input(
344
- "Enter the filename to upload as a supporting file (or 'n' to finish): "
410
+ "Enter the filename to upload as a supporting file (or '*' to get all files currently in this directory, or the index number of the file as displayed followed by a /, otherwise 'n' to finish): "
345
411
  )
346
- if filename == "n":
412
+ if filename == "*":
413
+ for files_name in files:
414
+ filepath = os.path.abspath(files_name)
415
+ filepaths.append(filepath)
416
+ print("All files added successfully")
417
+ elif filename == "n":
347
418
  break
348
- if filename in files:
419
+ elif (not len(filename) == 0) and (filename[len(filename) - 1] == "/"):
420
+ try:
421
+ files_name = files[int(filename[0]) - 1]
422
+ filepath = os.path.abspath(files_name)
423
+ filepaths.append(filepath)
424
+ print("File added successfully")
425
+ except ValueError:
426
+ continue
427
+ elif filename in files:
349
428
  file_size = os.path.getsize(filename)
350
429
  if file_size > 1024 * 1024 * 1024:
351
430
  print(
@@ -356,6 +435,7 @@ def upload_supporting_file(record_id=None):
356
435
  else:
357
436
  filepath = os.path.abspath(filename)
358
437
  filepaths.append(filepath)
438
+ print("File added successfully")
359
439
  else:
360
440
  print(
361
441
  f"Error: File '{filename}' not found. Please enter a valid filename."
@@ -405,24 +485,48 @@ def parse_args():
405
485
  parser.add_argument(
406
486
  "-test", action="store_true", help="Use test mode, sets production to False"
407
487
  )
488
+ parser.add_argument(
489
+ "--delete-token", action="store_true", help="Delete the saved token."
490
+ )
408
491
  args = parser.parse_args()
409
492
  return args
410
493
 
411
494
 
495
+ def normalize_orcid(val):
496
+ orcid_urls = ["https://orcid.org/", "http://orcid.org/", "orcid.org/"]
497
+ for orcid_url in orcid_urls:
498
+ if val.startswith(orcid_url):
499
+ val = val[len(orcid_url) :]
500
+ break
501
+
502
+ val = val.replace("-", "").replace(" ", "")
503
+ if len(val) != 16 or not val.isdigit():
504
+ raise ValueError(f"Invalid ORCID identifier: {val}")
505
+ return "-".join([val[0:4], val[4:8], val[8:12], val[12:16]])
506
+
507
+
412
508
  def main():
413
509
  args = parse_args()
510
+ production = not args.test
511
+ if args.delete_token:
512
+ delete_saved_token()
513
+ while True:
514
+ choice = get_user_input(
515
+ "What would you like to do? (create/edit/profile/exit): "
516
+ ).lower()
414
517
 
415
- production = not args.test # Set production to False if -test flag is provided
416
-
417
- choice = get_user_input(
418
- "Do you want to create or edit a CaltechDATA record? (create/edit): "
419
- ).lower()
420
- if choice == "create":
421
- create_record(production)
422
- elif choice == "edit":
423
- edit_record(production)
424
- else:
425
- print("Invalid choice. Please enter 'create' or 'edit'.")
518
+ if choice == "create":
519
+ create_record(production)
520
+ elif choice == "edit":
521
+ edit_record(production)
522
+ elif choice == "profile":
523
+ save_profile()
524
+ elif choice == "exit":
525
+ break
526
+ else:
527
+ print(
528
+ "Invalid choice. Please enter 'create', 'edit', 'profile', or 'exit'."
529
+ )
426
530
 
427
531
 
428
532
  def create_record(production):
@@ -521,6 +625,7 @@ def create_record(production):
521
625
  print_upload_message(rec_id, production)
522
626
  with open(response + ".json", "w") as file:
523
627
  json.dump(metadata, file, indent=2)
628
+ exit()
524
629
  break
525
630
  else:
526
631
  break
@@ -373,7 +373,8 @@ def customize_schema_rdm(json_record):
373
373
  if "community" in json_record:
374
374
  com = json_record.pop("community")
375
375
  parent["communities"] = {"ids": [com], "default": com}
376
- final["parent"] = parent
376
+ if parent != {}:
377
+ final["parent"] = parent
377
378
  # Not technically datacite, but transfer pids information
378
379
  if "pids" in json_record:
379
380
  final["pids"] = json_record.pop("pids")
@@ -408,11 +409,11 @@ def validate_metadata(json_record):
408
409
 
409
410
  # Publication date is handled by customize function
410
411
 
411
- # Check for 'resourceType'
412
- if "resourceType" not in json_record["types"]:
413
- errors.append("'resourceType' field is missing in 'types'.")
414
- elif not isinstance(json_record["types"]["resourceType"], str):
415
- errors.append("'resourceType' should be a string.")
412
+ # Check for 'resourceTypeGeneral'
413
+ if "resourceTypeGeneral" not in json_record["types"]:
414
+ errors.append("'resourceTypeGeneral' field is missing in 'types'.")
415
+ elif not isinstance(json_record["types"]["resourceTypeGeneral"], str):
416
+ errors.append("'resourceTypeGeneral' should be a string.")
416
417
 
417
418
  # Check for 'identifiers'
418
419
  if "identifiers" in json_record:
@@ -480,18 +481,17 @@ def validate_metadata(json_record):
480
481
  errors.append("Each 'subject' must have a 'subject' key.")
481
482
 
482
483
  # Check for 'dates'
483
- if "dates" not in json_record:
484
- errors.append("'dates' field is missing.")
485
- elif not isinstance(json_record["dates"], list) or len(json_record["dates"]) == 0:
486
- errors.append("'dates' should be a non-empty list.")
487
- else:
488
- for date in json_record["dates"]:
489
- if (
490
- not isinstance(date, dict)
491
- or "date" not in date
492
- or "dateType" not in date
493
- ):
494
- errors.append("Each 'date' must have 'date' and 'dateType'.")
484
+ if "dates" in json_record:
485
+ if not isinstance(json_record["dates"], list) or len(json_record["dates"]) == 0:
486
+ errors.append("'dates' should be a non-empty list.")
487
+ else:
488
+ for date in json_record["dates"]:
489
+ if (
490
+ not isinstance(date, dict)
491
+ or "date" not in date
492
+ or "dateType" not in date
493
+ ):
494
+ errors.append("Each 'date' must have 'date' and 'dateType'.")
495
495
 
496
496
  # Check for 'creators'
497
497
  if "creators" not in json_record:
@@ -509,11 +509,11 @@ def validate_metadata(json_record):
509
509
  if creator["nameType"] == "Organizational":
510
510
  if "name" not in creator:
511
511
  errors.append("Each organizational 'creator' must have 'name'.")
512
- else:
513
- if "familyName" not in creator:
514
- errors.append(
515
- "Each 'creator' must have a 'familyName' or have type Organizational"
516
- )
512
+ else:
513
+ if "familyName" not in creator:
514
+ errors.append(
515
+ "Each 'creator' must have a 'familyName' or have type Organizational"
516
+ )
517
517
  if "affiliation" in creator:
518
518
  if not isinstance(creator["affiliation"], list):
519
519
  errors.append("'affiliation' in 'creators' should be a list.")
@@ -601,10 +601,9 @@ def validate_metadata(json_record):
601
601
  errors.append("'publisher' should be a string.")
602
602
 
603
603
  # Check for 'publicationYear'
604
- if "publicationYear" not in json_record:
605
- errors.append("'publicationYear' field is missing.")
606
- elif not isinstance(json_record["publicationYear"], str):
607
- errors.append("'publicationYear' should be a string.")
604
+ if "publicationYear" in json_record:
605
+ if not isinstance(json_record["publicationYear"], str):
606
+ errors.append("'publicationYear' should be a string.")
608
607
 
609
608
  # Check for 'types'
610
609
  if "types" not in json_record:
@@ -1,23 +1,24 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: caltechdata-api
3
- Version: 1.9.1
3
+ Version: 1.10.1
4
4
  Summary: Python wrapper for CaltechDATA API.
5
5
  Home-page: https://github.com/caltechlibrary/caltechdata_api
6
- Author: Thomas E Morrell, Bhattarai Rohan , Won Elizabeth
7
- Author-email: tmorrell@caltech.edu, ,
8
- License: https://data.caltech.edu/license
6
+ Author: Thomas E Morrell, Rohan Bhattarai, Elizabeth Won, Alexander A Abakah, Kshemaahna Nagi
7
+ Author-email: tmorrell@caltech.edu, aabakah@caltech.edu, knagi@caltech.edu
8
+ License: MIT
9
9
  Platform: UNKNOWN
10
- Classifier: License :: OSI Approved :: BSD License
11
- Classifier: Programming Language :: Python
10
+ Classifier: License :: OSI Approved :: MIT License
12
11
  Classifier: Programming Language :: Python :: 3
13
12
  Classifier: Programming Language :: Python :: 3.7
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
14
16
  Classifier: Programming Language :: Python :: Implementation :: CPython
15
- Classifier: Programming Language :: Python :: Implementation :: PyPy
17
+ Classifier: Operating System :: OS Independent
16
18
  Requires-Python: >=3.6.0
17
19
  Description-Content-Type: text/markdown
18
20
  License-File: LICENSE
19
21
 
20
-
21
22
  # CaltechDATA API Python Library
22
23
 
23
24
  [![DOI](https://img.shields.io/badge/dynamic/json.svg?label=DOI&query=$.pids.doi.identifier&uri=https://data.caltech.edu/api/records/wfjr5-kw507/versions/latest)](https://data.caltech.edu/records/wfjr5-kw507/latest)
@@ -49,7 +50,7 @@ pip install caltechdata_api
49
50
 
50
51
  There are some example python scripts in the GitHub repository.
51
52
 
52
- ###Create a record:
53
+ ### Create a record:
53
54
 
54
55
  ```shell
55
56
  python write.py example.json -fnames logo.gif
@@ -59,7 +60,7 @@ python write.py example.json -fnames logo.gif
59
60
  the end of a url to visit the record (e.g.
60
61
  https://data.caltechlibrary.dev/records/pbkn6-m9y63)
61
62
 
62
- ###Edit a record
63
+ ### Edit a record
63
64
  Make changes to the example.json file to see a change)
64
65
  ```
65
66
  python edit.py example.json -id pbkn6-m9y63
@@ -97,5 +98,8 @@ This returns the custom DOI of the record if it is successful.
97
98
  Only test your application on the test repository (`data.caltechlibrary.dev`). Testing the API on the public
98
99
  repository will generate junk records that are annoying to delete.
99
100
 
101
+ ## Using the Command Line Interface
102
+
103
+ If you would like to interact with the CaltechDATA API using the Command line Interface (CLI), please [see the detailed documentation](https://caltechlibrary.github.io/caltechdata_api/caltechdata_api/cli-documentation-for-users).
100
104
 
101
105
 
@@ -1,5 +1,7 @@
1
1
  LICENSE
2
2
  README.md
3
+ pyproject.toml
4
+ setup.cfg
3
5
  setup.py
4
6
  caltechdata_api/__init__.py
5
7
  caltechdata_api/caltechdata_edit.py
@@ -0,0 +1,3 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,54 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64.0","wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [metadata]
6
+ name = caltechdata_api
7
+ version = 1.10.1
8
+ author = Thomas E Morrell, Rohan Bhattarai, Elizabeth Won, Alexander A Abakah, Kshemaahna Nagi
9
+ author_email = tmorrell@caltech.edu, aabakah@caltech.edu, knagi@caltech.edu
10
+ description = Python wrapper for CaltechDATA API.
11
+ long_description = file: README.md
12
+ long_description_content_type = text/markdown
13
+ url = https://github.com/caltechlibrary/caltechdata_api
14
+ license = MIT
15
+ classifiers =
16
+ License :: OSI Approved :: MIT License
17
+ Programming Language :: Python :: 3
18
+ Programming Language :: Python :: 3.7
19
+ Programming Language :: Python :: 3.8
20
+ Programming Language :: Python :: 3.9
21
+ Programming Language :: Python :: 3.10
22
+ Programming Language :: Python :: Implementation :: CPython
23
+ Operating System :: OS Independent
24
+
25
+ [options]
26
+ packages = find:
27
+ python_requires = >=3.6.0
28
+ install_requires =
29
+ requests
30
+ datacite>1.1.0
31
+ tqdm>=4.62.3
32
+ pyyaml
33
+ s3fs
34
+ cryptography
35
+ s3cmd
36
+ include_package_data = True
37
+
38
+ [options.packages.find]
39
+ exclude = tests
40
+
41
+ [options.package_data]
42
+ caltechdata_api = vocabularies.yaml, vocabularies/*
43
+
44
+ [options.entry_points]
45
+ console_scripts =
46
+ caltechdata_api=caltechdata_api.cli:main
47
+
48
+ [tool:pytest]
49
+ addopts = --verbose
50
+
51
+ [egg_info]
52
+ tag_build =
53
+ tag_date = 0
54
+
@@ -0,0 +1,3 @@
1
+ from setuptools import setup
2
+
3
+ setup()
@@ -1,4 +0,0 @@
1
- [egg_info]
2
- tag_build =
3
- tag_date = 0
4
-
@@ -1,179 +0,0 @@
1
- #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
-
4
- # Note: To use the 'upload' functionality of this file, you must:
5
- # $ pip install twine
6
-
7
- import io, json
8
- import os
9
- import sys
10
- import glob
11
- from shutil import rmtree
12
-
13
- from setuptools import find_packages, setup, Command
14
-
15
-
16
- def read(fname):
17
- with open(fname, mode="r", encoding="utf-8") as f:
18
- src = f.read()
19
- return src
20
-
21
-
22
- def package_files(package, directory):
23
- os.chdir(package)
24
- paths = glob.glob(directory + "/**", recursive=True)
25
- os.chdir("..")
26
- return paths
27
-
28
-
29
- codemeta_json = "codemeta.json"
30
-
31
- # Let's pickup as much metadata as we need from codemeta.json
32
- with open(codemeta_json, mode="r", encoding="utf-8") as f:
33
- src = f.read()
34
- meta = json.loads(src)
35
-
36
- # Let's make our symvar string
37
- version = meta["version"]
38
-
39
- # Now we need to pull and format our author, author_email strings.
40
- author = ""
41
- author_email = ""
42
- for obj in meta["author"]:
43
- given = obj.get("givenName", "")
44
- family = obj.get("familyName", "")
45
- email = obj.get("email", "")
46
- if len(author) == 0:
47
- author = given + " " + family
48
- else:
49
- author = author + ", " + given + " " + family
50
- if len(author_email) == 0:
51
- author_email = email
52
- else:
53
- author_email = author_email + ", " + email
54
- description = meta["description"]
55
- url = meta["codeRepository"]
56
- download = meta["downloadUrl"]
57
- license = meta["license"]
58
- name = meta["name"]
59
-
60
- REQUIRES_PYTHON = ">=3.6.0"
61
-
62
- # What packages are required for this module to be executed?
63
- REQUIRED = [
64
- "requests",
65
- "datacite>1.1.0",
66
- "tqdm>=4.62.3",
67
- "pyyaml",
68
- "s3fs",
69
- "cryptography",
70
- "s3cmd",
71
- ]
72
-
73
- # What packages are optional?
74
- EXTRAS = {
75
- # 'fancy feature': ['django'],
76
- }
77
-
78
- files = package_files("caltechdata_api", "vocabularies")
79
- files.append("vocabularies.yaml")
80
-
81
- # The rest you shouldn't have to touch too much :)
82
- # ------------------------------------------------
83
- # Except, perhaps the License and Trove Classifiers!
84
- # If you do change the License, remember to change the Trove Classifier for that!
85
-
86
- here = os.path.abspath(os.path.dirname(__file__))
87
-
88
- # Import the README and use it as the long-description.
89
- # Note: this will only work if 'README.md' is present in your MANIFEST.in file!
90
- try:
91
- with io.open(os.path.join(here, "README.md"), encoding="utf-8") as f:
92
- long_description = "\n" + f.read()
93
- except FileNotFoundError:
94
- long_description = description
95
-
96
- # Load the package's __version__.py module as a dictionary.
97
- about = {}
98
- if not version:
99
- with open(os.path.join(here, NAME, "__version__.py")) as f:
100
- exec(f.read(), about)
101
- else:
102
- about["__version__"] = version
103
-
104
-
105
- class UploadCommand(Command):
106
- """Support setup.py upload."""
107
-
108
- description = "Build and publish the package."
109
- user_options = []
110
-
111
- @staticmethod
112
- def status(s):
113
- """Prints things in bold."""
114
- print("\033[1m{0}\033[0m".format(s))
115
-
116
- def initialize_options(self):
117
- pass
118
-
119
- def finalize_options(self):
120
- pass
121
-
122
- def run(self):
123
- try:
124
- self.status("Removing previous builds…")
125
- rmtree(os.path.join(here, "dist"))
126
- except OSError:
127
- pass
128
-
129
- self.status("Building Source and Wheel distribution…")
130
- os.system("{0} setup.py sdist bdist_wheel ".format(sys.executable))
131
-
132
- self.status("Uploading the package to PyPI via Twine…")
133
- os.system("twine upload dist/*")
134
-
135
- sys.exit()
136
-
137
-
138
- # Where the magic happens:
139
- setup(
140
- name=name,
141
- version=about["__version__"],
142
- description=description,
143
- long_description=long_description,
144
- long_description_content_type="text/markdown",
145
- author=author,
146
- author_email=author_email,
147
- python_requires=REQUIRES_PYTHON,
148
- url=url,
149
- packages=find_packages(exclude=("tests",)),
150
- # If your package is a single module, use this instead of 'packages':
151
- # py_modules=['mypackage'],
152
- # entry_points={
153
- # 'console_scripts': ['mycli=mymodule:cli'],
154
- # },
155
- install_requires=REQUIRED,
156
- extras_require=EXTRAS,
157
- include_package_data=True,
158
- package_data={name: files},
159
- license=license,
160
- classifiers=[
161
- # Trove classifiers
162
- # Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers
163
- "License :: OSI Approved :: BSD License",
164
- "Programming Language :: Python",
165
- "Programming Language :: Python :: 3",
166
- "Programming Language :: Python :: 3.7",
167
- "Programming Language :: Python :: Implementation :: CPython",
168
- "Programming Language :: Python :: Implementation :: PyPy",
169
- ],
170
- # $ setup.py publish support.
171
- cmdclass={
172
- "upload": UploadCommand,
173
- },
174
- entry_points={
175
- "console_scripts": [
176
- "caltechdata_api=caltechdata_api.cli:main",
177
- ],
178
- },
179
- )