nci-cidc-api-modules 1.2.35__tar.gz → 1.2.38__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 (123) hide show
  1. {nci_cidc_api_modules-1.2.35/nci_cidc_api_modules.egg-info → nci_cidc_api_modules-1.2.38}/PKG-INFO +9 -1
  2. nci_cidc_api_modules-1.2.38/cidc_api/__init__.py +1 -0
  3. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/models.py +10 -2
  4. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/shared/assay_handling.py +1 -1
  5. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/shared/auth.py +5 -5
  6. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/shared/file_handling.py +3 -0
  7. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/shared/gcloud_client.py +4 -2
  8. nci_cidc_api_modules-1.2.38/cidc_api/shared/utils.py +19 -0
  9. nci_cidc_api_modules-1.2.38/cidc_api/telemetry.py +101 -0
  10. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38/nci_cidc_api_modules.egg-info}/PKG-INFO +9 -1
  11. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/nci_cidc_api_modules.egg-info/SOURCES.txt +2 -0
  12. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/nci_cidc_api_modules.egg-info/requires.txt +8 -0
  13. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/requirements.modules.txt +14 -0
  14. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/setup.py +3 -1
  15. nci_cidc_api_modules-1.2.35/cidc_api/shared/utils.py +0 -11
  16. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/LICENSE +0 -0
  17. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/MANIFEST.in +0 -0
  18. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/README.md +0 -0
  19. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/config/__init__.py +0 -0
  20. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/config/db.py +0 -0
  21. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/config/logging.py +0 -0
  22. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/config/secrets.py +0 -0
  23. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/config/settings.py +0 -0
  24. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/__init__.py +0 -0
  25. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/data.py +0 -0
  26. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/base_orm.py +0 -0
  27. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/__init__.py +0 -0
  28. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/additional_treatment_orm.py +0 -0
  29. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/administrative_person_orm.py +0 -0
  30. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/administrative_role_assignment_orm.py +0 -0
  31. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/adverse_event_orm.py +0 -0
  32. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/arm_orm.py +0 -0
  33. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/baseline_clinical_assessment_orm.py +0 -0
  34. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/cohort_orm.py +0 -0
  35. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/comorbidity_orm.py +0 -0
  36. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/consent_group_orm.py +0 -0
  37. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/contact_orm.py +0 -0
  38. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/demographic_orm.py +0 -0
  39. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/disease_orm.py +0 -0
  40. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/exposure_orm.py +0 -0
  41. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/file_orm.py +0 -0
  42. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/gvhd_diagnosis_acute_orm.py +0 -0
  43. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/gvhd_diagnosis_chronic_orm.py +0 -0
  44. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/gvhd_organ_acute_orm.py +0 -0
  45. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/gvhd_organ_chronic_orm.py +0 -0
  46. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/institution_orm.py +0 -0
  47. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/medical_history_orm.py +0 -0
  48. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/other_clinical_endpoint_orm.py +0 -0
  49. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/other_malignancy_orm.py +0 -0
  50. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/participant_orm.py +0 -0
  51. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/prior_treatment_orm.py +0 -0
  52. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/publication_orm.py +0 -0
  53. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/radiotherapy_dose_orm.py +0 -0
  54. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/response_by_system_orm.py +0 -0
  55. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/response_orm.py +0 -0
  56. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/shipment_orm.py +0 -0
  57. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/shipment_specimen_orm.py +0 -0
  58. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/specimen_orm.py +0 -0
  59. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/stem_cell_transplant_orm.py +0 -0
  60. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/surgery_orm.py +0 -0
  61. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/therapy_agent_dose_orm.py +0 -0
  62. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/treatment_orm.py +0 -0
  63. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/db/stage2/trial_orm.py +0 -0
  64. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/files/__init__.py +0 -0
  65. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/files/details.py +0 -0
  66. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/files/facets.py +0 -0
  67. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/migrations.py +0 -0
  68. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/__init__.py +0 -0
  69. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/additional_treatment.py +0 -0
  70. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/administrative_person.py +0 -0
  71. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/administrative_role_assignment.py +0 -0
  72. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/adverse_event.py +0 -0
  73. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/arm.py +0 -0
  74. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/base.py +0 -0
  75. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/baseline_clinical_assessment.py +0 -0
  76. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/cohort.py +0 -0
  77. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/comorbidity.py +0 -0
  78. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/consent_group.py +0 -0
  79. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/contact.py +0 -0
  80. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/demographic.py +0 -0
  81. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/disease.py +0 -0
  82. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/exposure.py +0 -0
  83. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/file.py +0 -0
  84. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/gvhd_diagnosis_acute.py +0 -0
  85. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/gvhd_diagnosis_chronic.py +0 -0
  86. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/gvhd_organ_acute.py +0 -0
  87. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/gvhd_organ_chronic.py +0 -0
  88. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/institution.py +0 -0
  89. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/medical_history.py +0 -0
  90. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/other_clinical_endpoint.py +0 -0
  91. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/other_malignancy.py +0 -0
  92. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/participant.py +0 -0
  93. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/prior_treatment.py +0 -0
  94. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/publication.py +0 -0
  95. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/radiotherapy_dose.py +0 -0
  96. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/response.py +0 -0
  97. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/response_by_system.py +0 -0
  98. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/shipment.py +0 -0
  99. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/shipment_specimen.py +0 -0
  100. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/specimen.py +0 -0
  101. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/stem_cell_transplant.py +0 -0
  102. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/surgery.py +0 -0
  103. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/therapy_agent_dose.py +0 -0
  104. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/treatment.py +0 -0
  105. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/pydantic/stage2/trial.py +0 -0
  106. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/schemas.py +0 -0
  107. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/models/types.py +0 -0
  108. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/reference/ctcae.py +0 -0
  109. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/reference/gvhd.py +0 -0
  110. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/reference/icd10cm.py +0 -0
  111. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/reference/icdo3.py +0 -0
  112. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/reference/uberon.py +0 -0
  113. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/shared/__init__.py +0 -0
  114. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/shared/email_layout.html +0 -0
  115. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/shared/emails.py +0 -0
  116. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/shared/jose.py +0 -0
  117. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/cidc_api/shared/rest_utils.py +0 -0
  118. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/nci_cidc_api_modules.egg-info/dependency_links.txt +0 -0
  119. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/nci_cidc_api_modules.egg-info/not-zip-safe +0 -0
  120. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/nci_cidc_api_modules.egg-info/top_level.txt +0 -0
  121. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/pyproject.toml +0 -0
  122. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/setup.cfg +0 -0
  123. {nci_cidc_api_modules-1.2.35 → nci_cidc_api_modules-1.2.38}/tests/test_api.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nci_cidc_api_modules
3
- Version: 1.2.35
3
+ Version: 1.2.38
4
4
  Summary: SQLAlchemy data models and configuration tools used in the NCI CIDC API
5
5
  Home-page: https://github.com/NCI-CIDC/cidc-api-gae
6
6
  License: MIT license
@@ -33,6 +33,14 @@ Requires-Dist: requests>=2.32.5
33
33
  Requires-Dist: sqlalchemy>=2.0.44
34
34
  Requires-Dist: sqlalchemy-mixins~=2.0.5
35
35
  Requires-Dist: werkzeug>=3.1.4
36
+ Requires-Dist: opentelemetry-api>=1.38.0
37
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.38.0
38
+ Requires-Dist: opentelemetry-sdk>=1.38.0
39
+ Requires-Dist: opentelemetry-instrumentation-flask>=0.59b0
40
+ Requires-Dist: opentelemetry-instrumentation-requests>=0.59b0
41
+ Requires-Dist: opentelemetry-instrumentation-sqlalchemy>=0.59b0
42
+ Requires-Dist: opentelemetry-exporter-gcp-trace>=1.11.0
43
+ Requires-Dist: opentelemetry-propagator-gcp>=1.11.0
36
44
  Requires-Dist: nci-cidc-schemas==0.28.10
37
45
  Dynamic: description
38
46
  Dynamic: description-content-type
@@ -0,0 +1 @@
1
+ __version__ = "1.2.38"
@@ -35,7 +35,8 @@ __all__ = [
35
35
  "ADMIN_FILE_CATEGORIES",
36
36
  "FINAL_JOB_STATUS",
37
37
  "INGESTION_JOB_STATUSES",
38
- "INGESTION_JOB_COLORS",
38
+ "ASSAY_JOB_COLORS",
39
+ "CLINICAL_JOB_COLORS",
39
40
  ]
40
41
 
41
42
  import hashlib
@@ -3436,7 +3437,7 @@ INGESTION_JOB_STATUSES = [
3436
3437
  ]
3437
3438
 
3438
3439
  # Business decision to pass hex codes from the backend though that should be done by the front end...
3439
- INGESTION_JOB_COLORS = {
3440
+ CLINICAL_JOB_COLORS = {
3440
3441
  "DRAFT": "",
3441
3442
  "INITIAL SUBMISSION": "#ACCAD7",
3442
3443
  "VALIDATION REVIEW": "#DABE90",
@@ -3444,6 +3445,13 @@ INGESTION_JOB_COLORS = {
3444
3445
  "INGESTION": "#8FCEC7",
3445
3446
  "PUBLISHED": "#90D9E6",
3446
3447
  }
3448
+ ASSAY_JOB_COLORS = {
3449
+ "INITIAL SUBMISSION": "#43807E",
3450
+ "VALIDATION REVIEW": "#906F3F",
3451
+ "REVISION SUBMISSION": "#95358A",
3452
+ "INGESTION": "#542C88",
3453
+ "PUBLISHED": "#1C81A0",
3454
+ }
3447
3455
  # TODO If have "CANCELLED" concept or other final status, add here
3448
3456
  FINAL_JOB_STATUS = ["PUBLISHED"]
3449
3457
  TRIAL_APPENDIX_A_CELL_THAT_ENDS_THE_HEADER = "Data Category"
@@ -53,7 +53,7 @@ def prepare_assay_job(trial_id: str, assay_type: str, batch_id: str) -> tuple[st
53
53
 
54
54
  # Create or retrieve intake bucket corresponding to the trial
55
55
  intake_bucket = gcloud_client.create_intake_bucket(get_current_user().email, trial_id=trial_id)
56
- gcs_path = f"{intake_bucket.name}/{trial_id}/{assay_type}"
56
+ gcs_path = f"{intake_bucket.name}/{assay_type}/{submission_id}"
57
57
 
58
58
  return submission_id, job_status, error_status, start_date, version, gcs_path
59
59
 
@@ -1,16 +1,14 @@
1
1
  from functools import wraps
2
2
  from typing import List
3
3
 
4
- from packaging import version
5
-
6
4
  from flask import g, request, current_app as app, Flask
5
+ from packaging import version
7
6
  from werkzeug.exceptions import Unauthorized, BadRequest, PreconditionFailed
8
7
 
9
- from ..models import Users, UserSchema
10
-
11
8
  from ..config.logging import get_logger
12
-
9
+ from ..models import Users, UserSchema
13
10
  from ..shared.jose import decode_id_token
11
+ from ..telemetry import trace_
14
12
 
15
13
  logger = get_logger(__name__)
16
14
 
@@ -144,6 +142,7 @@ def get_current_user() -> Users:
144
142
  _user_schema = UserSchema()
145
143
 
146
144
 
145
+ @trace_()
147
146
  def authenticate() -> Users:
148
147
  id_token = _extract_token()
149
148
  token_payload = decode_id_token(id_token)
@@ -172,6 +171,7 @@ def _extract_token() -> str:
172
171
 
173
172
 
174
173
  ### Authorization logic ###
174
+ @trace_()
175
175
  def authorize(user: Users, allowed_roles: List[str], resource: str, method: str) -> bool:
176
176
  """Check if the current user is authorized to act on the current request's resource.
177
177
  Raises Unauthorized
@@ -10,10 +10,12 @@ from ..config.settings import GOOGLE_CLINICAL_DATA_BUCKET
10
10
  from ..models import PreprocessedFiles, TRIAL_APPENDIX_A_CELL_THAT_ENDS_THE_HEADER
11
11
  from ..shared.auth import get_current_user
12
12
  from ..shared.gcloud_client import upload_file_to_gcs, move_gcs_file
13
+ from ..telemetry import trace_
13
14
 
14
15
  logger = get_logger(__name__)
15
16
 
16
17
 
18
+ @trace_()
17
19
  def set_current_file(
18
20
  file: FileStorage, file_category: str, gcs_folder: str, session: Session, uploader_email: str, job_id: int = None
19
21
  ) -> PreprocessedFiles:
@@ -26,6 +28,7 @@ def set_current_file(
26
28
  return latest_file
27
29
 
28
30
 
31
+ @trace_()
29
32
  def create_file(
30
33
  file: FileStorage,
31
34
  gcs_folder: str,
@@ -1,6 +1,6 @@
1
1
  """Utilities for interacting with the Google Cloud Platform APIs."""
2
2
 
3
- # pylint: disable=logging-fstring-interpolation,too-many-lines
3
+ # pylint: disable=logging-fstring-interpolation,too-many-lines, broad-exception-raised
4
4
 
5
5
  import base64
6
6
  import datetime
@@ -634,6 +634,7 @@ def _build_trial_upload_prefixes(
634
634
  trial_set: Set[str] = set()
635
635
  upload_set: Set[str] = set()
636
636
  if not trial_id:
637
+ # import is here becasue of circular import
637
638
  from ..models.models import TrialMetadata
638
639
 
639
640
  trial_set = {str(t.trial_id) for t in session.query(TrialMetadata).add_columns(TrialMetadata.trial_id)}
@@ -940,7 +941,8 @@ def get_signed_url(
940
941
 
941
942
  def _encode_and_publish(content: str, topic: str) -> Future:
942
943
  """Convert `content` to bytes and publish it to `topic`."""
943
- pubsub_publisher = pubsub.PublisherClient()
944
+ publisher_options = pubsub.types.PublisherOptions(enable_open_telemetry_tracing=ENV == "dev-int")
945
+ pubsub_publisher = pubsub.PublisherClient(publisher_options=publisher_options)
944
946
  topic = pubsub_publisher.topic_path(GOOGLE_CLOUD_PROJECT, topic)
945
947
  data = bytes(content, "utf-8")
946
948
 
@@ -0,0 +1,19 @@
1
+ from cidc_api.telemetry import trace_
2
+
3
+
4
+ def _stripper(x):
5
+ if x and isinstance(x, str):
6
+ return x.strip()
7
+ else:
8
+ return x
9
+
10
+
11
+ @trace_("sheet")
12
+ def strip_whitespaces(df, sheet=None):
13
+ if sheet:
14
+ df = df[sheet]
15
+
16
+ df.rename(columns=_stripper, inplace=True)
17
+ df = df.map(_stripper)
18
+
19
+ return df
@@ -0,0 +1,101 @@
1
+ # standard modules
2
+ from functools import wraps
3
+
4
+ # external modules
5
+ from opentelemetry import trace
6
+ from opentelemetry.sdk.resources import Resource
7
+ from opentelemetry.sdk.trace import TracerProvider
8
+ from opentelemetry.sdk.trace.export import BatchSpanProcessor
9
+
10
+ # local modules
11
+ from .config.settings import ENV, TESTING
12
+
13
+ # pylint: disable=import-outside-toplevel
14
+
15
+
16
+ def instrument_flask(app):
17
+ from opentelemetry.instrumentation.flask import FlaskInstrumentor
18
+ from opentelemetry.propagate import set_global_textmap
19
+ from opentelemetry.propagators.cloud_trace_propagator import CloudTraceFormatPropagator
20
+
21
+ FlaskInstrumentor().instrument_app(app)
22
+
23
+ # use the X-Cloud-Trace-Context header
24
+ set_global_textmap(CloudTraceFormatPropagator())
25
+
26
+
27
+ def instrument_requests():
28
+ from opentelemetry.instrumentation.requests import RequestsInstrumentor
29
+
30
+ def _request_hook(span, request_obj):
31
+ span.update_name(f"requests {request_obj.method}")
32
+
33
+ RequestsInstrumentor().instrument(request_hook=_request_hook)
34
+
35
+
36
+ def instrument_sqlachemy(engine):
37
+ from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
38
+
39
+ SQLAlchemyInstrumentor().instrument(engine=engine)
40
+
41
+
42
+ resource = Resource(attributes={"service.name": f"CIDC-{ENV}"})
43
+ provider = TracerProvider(resource=resource)
44
+
45
+
46
+ if ENV == "dev" and not TESTING:
47
+ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
48
+
49
+ COLLECTOR_ENDPOINT = "127.0.0.1"
50
+ COLLECTOR_GRPC_PORT = 6004
51
+
52
+ # send spans to local exporter
53
+ # 1. download latest version from https://github.com/open-telemetry/opentelemetry-collector-releases/releases (otelcol-contrib_0.140.1_darwin_arm64)
54
+ # 2. start exporter from otel folder with `./otelcol-contrib --config=config.yaml`
55
+ # 3. download and start Jeager (all-in-one image) - https://www.jaegertracing.io/download/
56
+ exporter = OTLPSpanExporter(endpoint=f"http://{COLLECTOR_ENDPOINT}:{COLLECTOR_GRPC_PORT}", insecure=True)
57
+ processor = BatchSpanProcessor(exporter)
58
+ provider.add_span_processor(processor)
59
+
60
+ if ENV == "dev-int":
61
+ from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
62
+
63
+ # send span to Cloud Trace service - https://console.cloud.google.com/traces/explorer
64
+ exporter = CloudTraceSpanExporter()
65
+ processor = BatchSpanProcessor(exporter)
66
+ provider.add_span_processor(processor)
67
+
68
+
69
+ # NOTE: we don't run telemetry in upper tiers; no span processor is noop
70
+
71
+ trace.set_tracer_provider(provider)
72
+ tracer = trace.get_tracer(__name__)
73
+
74
+
75
+ def trace_(*args):
76
+ def decorator_factory(func):
77
+
78
+ @wraps(func)
79
+ def wrapper(*args_, **kwargs_):
80
+ func_name = f"{func.__module__.split(".")[-1]}.{func.__name__}"
81
+
82
+ with tracer.start_as_current_span(func_name) as span:
83
+ for arg in args:
84
+ value = kwargs_.get(arg)
85
+
86
+ # track id of argument if exists
87
+ if hasattr(value, "id"):
88
+ value = getattr(value, "id")
89
+
90
+ span.set_attributes({arg: value})
91
+
92
+ result = func(*args_, **kwargs_)
93
+
94
+ if isinstance(result, (str, int, float, bool)):
95
+ span.set_attribute("result", result)
96
+
97
+ return result
98
+
99
+ return wrapper
100
+
101
+ return decorator_factory
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nci_cidc_api_modules
3
- Version: 1.2.35
3
+ Version: 1.2.38
4
4
  Summary: SQLAlchemy data models and configuration tools used in the NCI CIDC API
5
5
  Home-page: https://github.com/NCI-CIDC/cidc-api-gae
6
6
  License: MIT license
@@ -33,6 +33,14 @@ Requires-Dist: requests>=2.32.5
33
33
  Requires-Dist: sqlalchemy>=2.0.44
34
34
  Requires-Dist: sqlalchemy-mixins~=2.0.5
35
35
  Requires-Dist: werkzeug>=3.1.4
36
+ Requires-Dist: opentelemetry-api>=1.38.0
37
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.38.0
38
+ Requires-Dist: opentelemetry-sdk>=1.38.0
39
+ Requires-Dist: opentelemetry-instrumentation-flask>=0.59b0
40
+ Requires-Dist: opentelemetry-instrumentation-requests>=0.59b0
41
+ Requires-Dist: opentelemetry-instrumentation-sqlalchemy>=0.59b0
42
+ Requires-Dist: opentelemetry-exporter-gcp-trace>=1.11.0
43
+ Requires-Dist: opentelemetry-propagator-gcp>=1.11.0
36
44
  Requires-Dist: nci-cidc-schemas==0.28.10
37
45
  Dynamic: description
38
46
  Dynamic: description-content-type
@@ -4,6 +4,8 @@ README.md
4
4
  pyproject.toml
5
5
  requirements.modules.txt
6
6
  setup.py
7
+ cidc_api/__init__.py
8
+ cidc_api/telemetry.py
7
9
  cidc_api/config/__init__.py
8
10
  cidc_api/config/db.py
9
11
  cidc_api/config/logging.py
@@ -24,4 +24,12 @@ requests>=2.32.5
24
24
  sqlalchemy>=2.0.44
25
25
  sqlalchemy-mixins~=2.0.5
26
26
  werkzeug>=3.1.4
27
+ opentelemetry-api>=1.38.0
28
+ opentelemetry-exporter-otlp-proto-grpc>=1.38.0
29
+ opentelemetry-sdk>=1.38.0
30
+ opentelemetry-instrumentation-flask>=0.59b0
31
+ opentelemetry-instrumentation-requests>=0.59b0
32
+ opentelemetry-instrumentation-sqlalchemy>=0.59b0
33
+ opentelemetry-exporter-gcp-trace>=1.11.0
34
+ opentelemetry-propagator-gcp>=1.11.0
27
35
  nci-cidc-schemas==0.28.10
@@ -25,5 +25,19 @@ sqlalchemy>=2.0.44
25
25
  sqlalchemy-mixins~=2.0.5
26
26
  werkzeug>=3.1.4
27
27
 
28
+ # open telemetry sdk
29
+ opentelemetry-api >= 1.38.0
30
+ opentelemetry-exporter-otlp-proto-grpc >= 1.38.0
31
+ opentelemetry-sdk >= 1.38.0
32
+
33
+ # open telemetry instrumentation
34
+ opentelemetry-instrumentation-flask >= 0.59b0
35
+ opentelemetry-instrumentation-requests >= 0.59b0
36
+ opentelemetry-instrumentation-sqlalchemy >= 0.59b0
37
+
38
+ # open telemetry gcp
39
+ opentelemetry-exporter-gcp-trace >= 1.11.0
40
+ opentelemetry-propagator-gcp >= 1.11.0
41
+
28
42
  # cidc deps
29
43
  nci-cidc-schemas==0.28.10
@@ -13,15 +13,17 @@ from cidc_api import __version__
13
13
  packages = [
14
14
  "cidc_api.config",
15
15
  "cidc_api.models",
16
- "cidc_api.shared",
17
16
  "cidc_api.reference",
17
+ "cidc_api.shared",
18
18
  ]
19
19
  packages += find_namespace_packages(include=["cidc_api.models.*"])
20
20
  print(packages)
21
+
21
22
  setup(
22
23
  name="nci_cidc_api_modules",
23
24
  description="SQLAlchemy data models and configuration tools used in the NCI CIDC API",
24
25
  python_requires=">=3.13",
26
+ py_modules=["cidc_api.telemetry"],
25
27
  install_requires=requirements,
26
28
  license="MIT license",
27
29
  include_package_data=True,
@@ -1,11 +0,0 @@
1
- def strip_whitespaces(df):
2
- def stripper(x):
3
- if x and isinstance(x, str):
4
- return x.strip()
5
- else:
6
- return x
7
-
8
- df.rename(columns=stripper, inplace=True)
9
- df = df.map(stripper)
10
-
11
- return df