caltechdata-api 1.9.1__tar.gz → 1.10.0__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.0}/PKG-INFO +11 -10
  2. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/README.md +2 -2
  3. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/caltechdata_api/__init__.py +2 -1
  4. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/caltechdata_api/caltechdata_edit.py +8 -4
  5. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/caltechdata_api/cli.py +120 -31
  6. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/caltechdata_api/customize_schema.py +26 -27
  7. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/caltechdata_api.egg-info/PKG-INFO +11 -10
  8. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/caltechdata_api.egg-info/SOURCES.txt +2 -0
  9. caltechdata_api-1.10.0/pyproject.toml +3 -0
  10. caltechdata_api-1.10.0/setup.cfg +54 -0
  11. caltechdata_api-1.10.0/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.0}/LICENSE +0 -0
  15. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/caltechdata_api/caltechdata_write.py +0 -0
  16. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/caltechdata_api/download_file.py +0 -0
  17. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/caltechdata_api/get_files.py +0 -0
  18. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/caltechdata_api/get_metadata.py +0 -0
  19. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/caltechdata_api/md_to_json.py +0 -0
  20. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/caltechdata_api/utils.py +0 -0
  21. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/caltechdata_api.egg-info/dependency_links.txt +0 -0
  22. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/caltechdata_api.egg-info/entry_points.txt +0 -0
  23. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/caltechdata_api.egg-info/requires.txt +0 -0
  24. {caltechdata_api-1.9.1 → caltechdata_api-1.10.0}/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.0
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
7
+ Author-email: tmorrell@caltech.edu, aabakah@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
@@ -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
@@ -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
 
@@ -405,24 +469,48 @@ def parse_args():
405
469
  parser.add_argument(
406
470
  "-test", action="store_true", help="Use test mode, sets production to False"
407
471
  )
472
+ parser.add_argument(
473
+ "--delete-token", action="store_true", help="Delete the saved token."
474
+ )
408
475
  args = parser.parse_args()
409
476
  return args
410
477
 
411
478
 
479
+ def normalize_orcid(val):
480
+ orcid_urls = ["https://orcid.org/", "http://orcid.org/", "orcid.org/"]
481
+ for orcid_url in orcid_urls:
482
+ if val.startswith(orcid_url):
483
+ val = val[len(orcid_url) :]
484
+ break
485
+
486
+ val = val.replace("-", "").replace(" ", "")
487
+ if len(val) != 16 or not val.isdigit():
488
+ raise ValueError(f"Invalid ORCID identifier: {val}")
489
+ return "-".join([val[0:4], val[4:8], val[8:12], val[12:16]])
490
+
491
+
412
492
  def main():
413
493
  args = parse_args()
494
+ production = not args.test
495
+ if args.delete_token:
496
+ delete_saved_token()
497
+ while True:
498
+ choice = get_user_input(
499
+ "What would you like to do? (create/edit/profile/exit): "
500
+ ).lower()
414
501
 
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'.")
502
+ if choice == "create":
503
+ create_record(production)
504
+ elif choice == "edit":
505
+ edit_record(production)
506
+ elif choice == "profile":
507
+ save_profile()
508
+ elif choice == "exit":
509
+ break
510
+ else:
511
+ print(
512
+ "Invalid choice. Please enter 'create', 'edit', 'profile', or 'exit'."
513
+ )
426
514
 
427
515
 
428
516
  def create_record(production):
@@ -521,6 +609,7 @@ def create_record(production):
521
609
  print_upload_message(rec_id, production)
522
610
  with open(response + ".json", "w") as file:
523
611
  json.dump(metadata, file, indent=2)
612
+ exit()
524
613
  break
525
614
  else:
526
615
  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.0
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
7
+ Author-email: tmorrell@caltech.edu, aabakah@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
@@ -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.0
8
+ author = Thomas E Morrell, Rohan Bhattarai, Elizabeth Won, Alexander A Abakah
9
+ author_email = tmorrell@caltech.edu, aabakah@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
- )