tango-python 0.4.0__py3-none-any.whl → 0.4.1__py3-none-any.whl
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.
- tango/__init__.py +3 -1
- tango/client.py +458 -151
- tango/models.py +18 -0
- tango/shapes/explicit_schemas.py +39 -0
- {tango_python-0.4.0.dist-info → tango_python-0.4.1.dist-info}/METADATA +1 -1
- {tango_python-0.4.0.dist-info → tango_python-0.4.1.dist-info}/RECORD +8 -8
- {tango_python-0.4.0.dist-info → tango_python-0.4.1.dist-info}/WHEEL +0 -0
- {tango_python-0.4.0.dist-info → tango_python-0.4.1.dist-info}/licenses/LICENSE +0 -0
tango/__init__.py
CHANGED
|
@@ -9,6 +9,7 @@ from .exceptions import (
|
|
|
9
9
|
TangoValidationError,
|
|
10
10
|
)
|
|
11
11
|
from .models import (
|
|
12
|
+
GsaElibraryContract,
|
|
12
13
|
PaginatedResponse,
|
|
13
14
|
SearchFilters,
|
|
14
15
|
ShapeConfig,
|
|
@@ -26,7 +27,7 @@ from .shapes import (
|
|
|
26
27
|
TypeGenerator,
|
|
27
28
|
)
|
|
28
29
|
|
|
29
|
-
__version__ = "0.4.
|
|
30
|
+
__version__ = "0.4.1"
|
|
30
31
|
__all__ = [
|
|
31
32
|
"TangoClient",
|
|
32
33
|
"TangoAPIError",
|
|
@@ -34,6 +35,7 @@ __all__ = [
|
|
|
34
35
|
"TangoNotFoundError",
|
|
35
36
|
"TangoValidationError",
|
|
36
37
|
"TangoRateLimitError",
|
|
38
|
+
"GsaElibraryContract",
|
|
37
39
|
"PaginatedResponse",
|
|
38
40
|
"SearchFilters",
|
|
39
41
|
"ShapeConfig",
|
tango/client.py
CHANGED
|
@@ -25,6 +25,7 @@ from tango.models import (
|
|
|
25
25
|
Entity,
|
|
26
26
|
Forecast,
|
|
27
27
|
Grant,
|
|
28
|
+
GsaElibraryContract,
|
|
28
29
|
Location,
|
|
29
30
|
Notice,
|
|
30
31
|
Opportunity,
|
|
@@ -496,7 +497,34 @@ class TangoClient:
|
|
|
496
497
|
flat: bool = False,
|
|
497
498
|
flat_lists: bool = False,
|
|
498
499
|
filters: SearchFilters | dict[str, Any] | None = None,
|
|
499
|
-
|
|
500
|
+
award_date: str | None = None,
|
|
501
|
+
award_date_gte: str | None = None,
|
|
502
|
+
award_date_lte: str | None = None,
|
|
503
|
+
award_type: str | None = None,
|
|
504
|
+
awarding_agency: str | None = None,
|
|
505
|
+
expiring_gte: str | None = None,
|
|
506
|
+
expiring_lte: str | None = None,
|
|
507
|
+
fiscal_year: int | None = None,
|
|
508
|
+
fiscal_year_gte: int | None = None,
|
|
509
|
+
fiscal_year_lte: int | None = None,
|
|
510
|
+
funding_agency: str | None = None,
|
|
511
|
+
obligated_gte: str | None = None,
|
|
512
|
+
obligated_lte: str | None = None,
|
|
513
|
+
ordering: str | None = None,
|
|
514
|
+
piid: str | None = None,
|
|
515
|
+
pop_end_date_gte: str | None = None,
|
|
516
|
+
pop_end_date_lte: str | None = None,
|
|
517
|
+
pop_start_date_gte: str | None = None,
|
|
518
|
+
pop_start_date_lte: str | None = None,
|
|
519
|
+
solicitation_identifier: str | None = None,
|
|
520
|
+
keyword: str | None = None,
|
|
521
|
+
naics_code: str | None = None,
|
|
522
|
+
psc_code: str | None = None,
|
|
523
|
+
recipient_name: str | None = None,
|
|
524
|
+
recipient_uei: str | None = None,
|
|
525
|
+
set_aside_type: str | None = None,
|
|
526
|
+
sort: str | None = None,
|
|
527
|
+
order: str | None = None,
|
|
500
528
|
) -> PaginatedResponse:
|
|
501
529
|
"""
|
|
502
530
|
List contracts with optional filtering
|
|
@@ -511,118 +539,61 @@ class TangoClient:
|
|
|
511
539
|
flat: If True, flatten nested objects in shaped response using dot notation
|
|
512
540
|
flat_lists: If True, flatten arrays using indexed keys (e.g., items.0.field)
|
|
513
541
|
filters: Optional SearchFilters object or dict for backward compatibility.
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
- fiscal_year: Fiscal year (exact match)
|
|
543
|
-
- fiscal_year_gte: Fiscal year >=
|
|
544
|
-
- fiscal_year_lte: Fiscal year <=
|
|
545
|
-
- award_type: Award type code
|
|
546
|
-
|
|
547
|
-
Identifiers:
|
|
548
|
-
- piid: Procurement Instrument Identifier
|
|
549
|
-
- solicitation_identifier: Solicitation ID
|
|
550
|
-
|
|
551
|
-
Sorting:
|
|
552
|
-
- sort: Field to sort by (combined with 'order')
|
|
553
|
-
- order: Sort order ('asc' or 'desc', default 'asc')
|
|
542
|
+
award_date: Award date (exact match, YYYY-MM-DD)
|
|
543
|
+
award_date_gte: Award date >= (YYYY-MM-DD)
|
|
544
|
+
award_date_lte: Award date <= (YYYY-MM-DD)
|
|
545
|
+
award_type: Award type code
|
|
546
|
+
awarding_agency: Awarding agency code (e.g., "4700" for GSA)
|
|
547
|
+
expiring_gte: Expiring on or after date
|
|
548
|
+
expiring_lte: Expiring on or before date
|
|
549
|
+
fiscal_year: Fiscal year (exact match)
|
|
550
|
+
fiscal_year_gte: Fiscal year >=
|
|
551
|
+
fiscal_year_lte: Fiscal year <=
|
|
552
|
+
funding_agency: Funding agency code
|
|
553
|
+
obligated_gte: Obligated amount >=
|
|
554
|
+
obligated_lte: Obligated amount <=
|
|
555
|
+
ordering: Sort ordering (prefix with '-' for descending)
|
|
556
|
+
piid: Procurement Instrument Identifier
|
|
557
|
+
pop_end_date_gte: Period of performance end date >=
|
|
558
|
+
pop_end_date_lte: Period of performance end date <=
|
|
559
|
+
pop_start_date_gte: Period of performance start date >=
|
|
560
|
+
pop_start_date_lte: Period of performance start date <=
|
|
561
|
+
solicitation_identifier: Solicitation ID
|
|
562
|
+
keyword: Search contract descriptions (mapped to 'search' API param)
|
|
563
|
+
naics_code: NAICS code (mapped to 'naics' API param)
|
|
564
|
+
psc_code: PSC code (mapped to 'psc' API param)
|
|
565
|
+
recipient_name: Vendor/recipient name (mapped to 'recipient' API param)
|
|
566
|
+
recipient_uei: Vendor UEI (mapped to 'uei' API param)
|
|
567
|
+
set_aside_type: Set-aside type (mapped to 'set_aside' API param)
|
|
568
|
+
sort: Field to sort by (combined with 'order' to produce 'ordering')
|
|
569
|
+
order: Sort order ('asc' or 'desc', default 'asc')
|
|
554
570
|
|
|
555
571
|
Examples:
|
|
556
|
-
>>> # Simple usage
|
|
557
572
|
>>> contracts = client.list_contracts(limit=10)
|
|
558
|
-
|
|
559
|
-
>>> # With keyword arguments
|
|
560
573
|
>>> contracts = client.list_contracts(
|
|
561
|
-
... awarding_agency="4700",
|
|
574
|
+
... awarding_agency="4700",
|
|
562
575
|
... award_date_gte="2023-01-01",
|
|
563
|
-
... limit=25
|
|
576
|
+
... limit=25,
|
|
564
577
|
... )
|
|
565
|
-
|
|
566
|
-
>>> # Text search
|
|
567
578
|
>>> contracts = client.list_contracts(keyword="software development")
|
|
568
|
-
|
|
569
|
-
>>> # Pagination with cursor
|
|
570
|
-
>>> response = client.list_contracts(limit=25)
|
|
571
|
-
>>> if response.cursor:
|
|
572
|
-
... next_page = client.list_contracts(cursor=response.cursor, limit=25)
|
|
573
|
-
|
|
574
|
-
>>> # With SearchFilters object (legacy)
|
|
575
|
-
>>> filters = SearchFilters(
|
|
576
|
-
... keyword="IT",
|
|
577
|
-
... awarding_agency="4700",
|
|
578
|
-
... fiscal_year=2024
|
|
579
|
-
... )
|
|
580
|
-
>>> contracts = client.list_contracts(filters=filters)
|
|
581
|
-
|
|
582
|
-
>>> # Using new date range filters
|
|
583
|
-
>>> contracts = client.list_contracts(
|
|
584
|
-
... expiring_gte="2025-01-01",
|
|
585
|
-
... expiring_lte="2025-12-31"
|
|
586
|
-
... )
|
|
587
579
|
"""
|
|
588
|
-
# Start with pagination parameters
|
|
589
|
-
# Use cursor if provided, otherwise use page=1 for first request
|
|
590
580
|
params: dict[str, Any] = {"limit": min(limit, 100)}
|
|
591
581
|
if cursor:
|
|
592
582
|
params["cursor"] = cursor
|
|
593
583
|
else:
|
|
594
|
-
# First page uses page=1, subsequent pages use cursor
|
|
595
584
|
params["page"] = 1
|
|
596
585
|
|
|
597
|
-
# Handle filters parameter (backward compatibility)
|
|
586
|
+
# Handle legacy filters parameter (backward compatibility)
|
|
598
587
|
filter_dict: dict[str, Any] = {}
|
|
599
588
|
if filters is not None:
|
|
600
589
|
if hasattr(filters, "to_dict"):
|
|
601
|
-
# SearchFilters object
|
|
602
590
|
filter_dict = filters.to_dict()
|
|
603
591
|
else:
|
|
604
|
-
|
|
605
|
-
filter_dict = filters
|
|
592
|
+
filter_dict = dict(filters)
|
|
606
593
|
|
|
607
|
-
# Extract limit from filters if using defaults
|
|
608
594
|
if limit == 25 and "limit" in filter_dict:
|
|
609
595
|
params["limit"] = min(filter_dict.pop("limit", 25), 100)
|
|
610
596
|
|
|
611
|
-
# Merge kwargs and filter_dict (kwargs take precedence)
|
|
612
|
-
filter_params = {**filter_dict, **kwargs}
|
|
613
|
-
|
|
614
|
-
# Explicitly exclude shape-related and pagination parameters from filter_params
|
|
615
|
-
# These are handled separately and should not be sent as query parameters
|
|
616
|
-
excluded_params = {"shape", "flat", "flat_lists", "cursor", "page"}
|
|
617
|
-
for param in excluded_params:
|
|
618
|
-
filter_params.pop(param, None)
|
|
619
|
-
|
|
620
|
-
# Extract limit from kwargs if provided (override explicit params)
|
|
621
|
-
if "limit" in filter_params:
|
|
622
|
-
params["limit"] = min(filter_params.pop("limit"), 100)
|
|
623
|
-
|
|
624
|
-
# Add shape parameter with default minimal shape
|
|
625
|
-
# This is separate from filter parameters and controls response fields, not filtering
|
|
626
597
|
if shape is None:
|
|
627
598
|
shape = ShapeConfig.CONTRACTS_MINIMAL
|
|
628
599
|
if shape:
|
|
@@ -632,43 +603,65 @@ class TangoClient:
|
|
|
632
603
|
if flat_lists:
|
|
633
604
|
params["flat_lists"] = "true"
|
|
634
605
|
|
|
635
|
-
# Process filter parameters - convert award amounts to strings
|
|
636
|
-
# Map Python parameter names to API parameter names if needed
|
|
637
|
-
# Then update params with all filters (excluding None values)
|
|
638
|
-
# This matches the pattern used by other endpoints (params.update(filters))
|
|
639
|
-
|
|
640
|
-
# Map Python parameter names to API parameter names
|
|
641
|
-
# The API may expect different parameter names than our Python interface
|
|
642
606
|
api_param_mapping = {
|
|
643
|
-
"naics_code": "naics",
|
|
644
|
-
"keyword": "search",
|
|
645
|
-
"psc_code": "psc",
|
|
646
|
-
"recipient_name": "recipient",
|
|
647
|
-
"recipient_uei": "uei",
|
|
648
|
-
"set_aside_type": "set_aside",
|
|
607
|
+
"naics_code": "naics",
|
|
608
|
+
"keyword": "search",
|
|
609
|
+
"psc_code": "psc",
|
|
610
|
+
"recipient_name": "recipient",
|
|
611
|
+
"recipient_uei": "uei",
|
|
612
|
+
"set_aside_type": "set_aside",
|
|
649
613
|
}
|
|
650
614
|
|
|
615
|
+
# Collect explicit filter params; legacy filter_dict values are used as fallback
|
|
616
|
+
filter_params: dict[str, Any] = {}
|
|
617
|
+
for key, val in (
|
|
618
|
+
("award_date", award_date),
|
|
619
|
+
("award_date_gte", award_date_gte),
|
|
620
|
+
("award_date_lte", award_date_lte),
|
|
621
|
+
("award_type", award_type),
|
|
622
|
+
("awarding_agency", awarding_agency),
|
|
623
|
+
("expiring_gte", expiring_gte),
|
|
624
|
+
("expiring_lte", expiring_lte),
|
|
625
|
+
("fiscal_year", fiscal_year),
|
|
626
|
+
("fiscal_year_gte", fiscal_year_gte),
|
|
627
|
+
("fiscal_year_lte", fiscal_year_lte),
|
|
628
|
+
("funding_agency", funding_agency),
|
|
629
|
+
("obligated_gte", obligated_gte),
|
|
630
|
+
("obligated_lte", obligated_lte),
|
|
631
|
+
("ordering", ordering),
|
|
632
|
+
("piid", piid),
|
|
633
|
+
("pop_end_date_gte", pop_end_date_gte),
|
|
634
|
+
("pop_end_date_lte", pop_end_date_lte),
|
|
635
|
+
("pop_start_date_gte", pop_start_date_gte),
|
|
636
|
+
("pop_start_date_lte", pop_start_date_lte),
|
|
637
|
+
("solicitation_identifier", solicitation_identifier),
|
|
638
|
+
("keyword", keyword),
|
|
639
|
+
("naics_code", naics_code),
|
|
640
|
+
("psc_code", psc_code),
|
|
641
|
+
("recipient_name", recipient_name),
|
|
642
|
+
("recipient_uei", recipient_uei),
|
|
643
|
+
("set_aside_type", set_aside_type),
|
|
644
|
+
):
|
|
645
|
+
if val is not None:
|
|
646
|
+
filter_params[key] = val
|
|
647
|
+
|
|
648
|
+
# Merge: explicit params take precedence over legacy filter_dict
|
|
649
|
+
excluded = {"shape", "flat", "flat_lists", "cursor", "page", "limit"}
|
|
650
|
+
for k, v in filter_dict.items():
|
|
651
|
+
if k not in excluded and k not in filter_params and v is not None:
|
|
652
|
+
filter_params[k] = v
|
|
653
|
+
|
|
651
654
|
# Handle sort + order → ordering conversion
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
if sort_field:
|
|
656
|
-
# Prefix with '-' for descending order
|
|
655
|
+
sort_field = sort or filter_dict.get("sort")
|
|
656
|
+
sort_order = order or filter_dict.get("order")
|
|
657
|
+
if sort_field and "ordering" not in filter_params:
|
|
657
658
|
prefix = "-" if sort_order == "desc" else ""
|
|
658
659
|
filter_params["ordering"] = f"{prefix}{sort_field}"
|
|
659
660
|
|
|
660
|
-
# Apply parameter name mapping and
|
|
661
|
-
api_params = {}
|
|
661
|
+
# Apply parameter name mapping and add to params
|
|
662
662
|
for key, value in filter_params.items():
|
|
663
|
-
if value is None:
|
|
664
|
-
continue # Skip None values
|
|
665
|
-
# Map to API parameter name if needed
|
|
666
663
|
api_key = api_param_mapping.get(key, key)
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
# Update params with all filter parameters
|
|
670
|
-
# This is the same pattern as other endpoints use
|
|
671
|
-
params.update(api_params)
|
|
664
|
+
params[api_key] = value
|
|
672
665
|
|
|
673
666
|
data = self._get("/api/contracts/", params)
|
|
674
667
|
|
|
@@ -698,7 +691,30 @@ class TangoClient:
|
|
|
698
691
|
flat: bool = False,
|
|
699
692
|
flat_lists: bool = False,
|
|
700
693
|
joiner: str = ".",
|
|
701
|
-
|
|
694
|
+
award_date: str | None = None,
|
|
695
|
+
award_date_gte: str | None = None,
|
|
696
|
+
award_date_lte: str | None = None,
|
|
697
|
+
awarding_agency: str | None = None,
|
|
698
|
+
expiring_gte: str | None = None,
|
|
699
|
+
expiring_lte: str | None = None,
|
|
700
|
+
fiscal_year: int | None = None,
|
|
701
|
+
fiscal_year_gte: int | None = None,
|
|
702
|
+
fiscal_year_lte: int | None = None,
|
|
703
|
+
funding_agency: str | None = None,
|
|
704
|
+
idv_type: str | None = None,
|
|
705
|
+
last_date_to_order_gte: str | None = None,
|
|
706
|
+
last_date_to_order_lte: str | None = None,
|
|
707
|
+
naics: str | None = None,
|
|
708
|
+
ordering: str | None = None,
|
|
709
|
+
piid: str | None = None,
|
|
710
|
+
pop_start_date_gte: str | None = None,
|
|
711
|
+
pop_start_date_lte: str | None = None,
|
|
712
|
+
psc: str | None = None,
|
|
713
|
+
recipient: str | None = None,
|
|
714
|
+
search: str | None = None,
|
|
715
|
+
set_aside: str | None = None,
|
|
716
|
+
solicitation_identifier: str | None = None,
|
|
717
|
+
uei: str | None = None,
|
|
702
718
|
) -> PaginatedResponse:
|
|
703
719
|
"""
|
|
704
720
|
List IDVs (indefinite delivery vehicles) with keyset pagination.
|
|
@@ -721,7 +737,34 @@ class TangoClient:
|
|
|
721
737
|
if flat_lists:
|
|
722
738
|
params["flat_lists"] = "true"
|
|
723
739
|
|
|
724
|
-
|
|
740
|
+
for key, val in (
|
|
741
|
+
("award_date", award_date),
|
|
742
|
+
("award_date_gte", award_date_gte),
|
|
743
|
+
("award_date_lte", award_date_lte),
|
|
744
|
+
("awarding_agency", awarding_agency),
|
|
745
|
+
("expiring_gte", expiring_gte),
|
|
746
|
+
("expiring_lte", expiring_lte),
|
|
747
|
+
("fiscal_year", fiscal_year),
|
|
748
|
+
("fiscal_year_gte", fiscal_year_gte),
|
|
749
|
+
("fiscal_year_lte", fiscal_year_lte),
|
|
750
|
+
("funding_agency", funding_agency),
|
|
751
|
+
("idv_type", idv_type),
|
|
752
|
+
("last_date_to_order_gte", last_date_to_order_gte),
|
|
753
|
+
("last_date_to_order_lte", last_date_to_order_lte),
|
|
754
|
+
("naics", naics),
|
|
755
|
+
("ordering", ordering),
|
|
756
|
+
("piid", piid),
|
|
757
|
+
("pop_start_date_gte", pop_start_date_gte),
|
|
758
|
+
("pop_start_date_lte", pop_start_date_lte),
|
|
759
|
+
("psc", psc),
|
|
760
|
+
("recipient", recipient),
|
|
761
|
+
("search", search),
|
|
762
|
+
("set_aside", set_aside),
|
|
763
|
+
("solicitation_identifier", solicitation_identifier),
|
|
764
|
+
("uei", uei),
|
|
765
|
+
):
|
|
766
|
+
if val is not None:
|
|
767
|
+
params[key] = val
|
|
725
768
|
|
|
726
769
|
data = self._get("/api/idvs/", params)
|
|
727
770
|
|
|
@@ -1188,6 +1231,88 @@ class TangoClient:
|
|
|
1188
1231
|
results=results,
|
|
1189
1232
|
)
|
|
1190
1233
|
|
|
1234
|
+
# ============================================================================
|
|
1235
|
+
# GSA eLibrary Contracts
|
|
1236
|
+
# ============================================================================
|
|
1237
|
+
|
|
1238
|
+
def list_gsa_elibrary_contracts(
|
|
1239
|
+
self,
|
|
1240
|
+
page: int = 1,
|
|
1241
|
+
limit: int = 25,
|
|
1242
|
+
shape: str | None = None,
|
|
1243
|
+
flat: bool = False,
|
|
1244
|
+
flat_lists: bool = False,
|
|
1245
|
+
joiner: str = ".",
|
|
1246
|
+
contract_number: str | None = None,
|
|
1247
|
+
key: str | None = None,
|
|
1248
|
+
piid: str | None = None,
|
|
1249
|
+
schedule: str | None = None,
|
|
1250
|
+
search: str | None = None,
|
|
1251
|
+
sin: str | None = None,
|
|
1252
|
+
uei: str | None = None,
|
|
1253
|
+
) -> PaginatedResponse:
|
|
1254
|
+
"""List GSA eLibrary contracts (`/api/gsa_elibrary_contracts/`)."""
|
|
1255
|
+
params: dict[str, Any] = {"page": page, "limit": min(limit, 100)}
|
|
1256
|
+
if shape is None:
|
|
1257
|
+
shape = ShapeConfig.GSA_ELIBRARY_CONTRACTS_MINIMAL
|
|
1258
|
+
if shape:
|
|
1259
|
+
params["shape"] = shape
|
|
1260
|
+
if flat:
|
|
1261
|
+
params["flat"] = "true"
|
|
1262
|
+
if joiner:
|
|
1263
|
+
params["joiner"] = joiner
|
|
1264
|
+
if flat_lists:
|
|
1265
|
+
params["flat_lists"] = "true"
|
|
1266
|
+
for k, val in (
|
|
1267
|
+
("contract_number", contract_number),
|
|
1268
|
+
("key", key),
|
|
1269
|
+
("piid", piid),
|
|
1270
|
+
("schedule", schedule),
|
|
1271
|
+
("search", search),
|
|
1272
|
+
("sin", sin),
|
|
1273
|
+
("uei", uei),
|
|
1274
|
+
):
|
|
1275
|
+
if val is not None:
|
|
1276
|
+
params[k] = val
|
|
1277
|
+
data = self._get("/api/gsa_elibrary_contracts/", params)
|
|
1278
|
+
results = [
|
|
1279
|
+
self._parse_response_with_shape(
|
|
1280
|
+
obj, shape, GsaElibraryContract, flat, flat_lists, joiner=joiner
|
|
1281
|
+
)
|
|
1282
|
+
for obj in data.get("results", [])
|
|
1283
|
+
]
|
|
1284
|
+
return PaginatedResponse(
|
|
1285
|
+
count=data.get("count", 0),
|
|
1286
|
+
next=data.get("next"),
|
|
1287
|
+
previous=data.get("previous"),
|
|
1288
|
+
results=results,
|
|
1289
|
+
)
|
|
1290
|
+
|
|
1291
|
+
def get_gsa_elibrary_contract(
|
|
1292
|
+
self,
|
|
1293
|
+
uuid: str,
|
|
1294
|
+
shape: str | None = None,
|
|
1295
|
+
flat: bool = False,
|
|
1296
|
+
flat_lists: bool = False,
|
|
1297
|
+
joiner: str = ".",
|
|
1298
|
+
) -> Any:
|
|
1299
|
+
"""Get a single GSA eLibrary contract by UUID (`/api/gsa_elibrary_contracts/{uuid}/`)."""
|
|
1300
|
+
params: dict[str, Any] = {}
|
|
1301
|
+
if shape is None:
|
|
1302
|
+
shape = ShapeConfig.GSA_ELIBRARY_CONTRACTS_MINIMAL
|
|
1303
|
+
if shape:
|
|
1304
|
+
params["shape"] = shape
|
|
1305
|
+
if flat:
|
|
1306
|
+
params["flat"] = "true"
|
|
1307
|
+
if joiner:
|
|
1308
|
+
params["joiner"] = joiner
|
|
1309
|
+
if flat_lists:
|
|
1310
|
+
params["flat_lists"] = "true"
|
|
1311
|
+
data = self._get(f"/api/gsa_elibrary_contracts/{uuid}/", params)
|
|
1312
|
+
return self._parse_response_with_shape(
|
|
1313
|
+
data, shape, GsaElibraryContract, flat, flat_lists, joiner=joiner
|
|
1314
|
+
)
|
|
1315
|
+
|
|
1191
1316
|
# ============================================================================
|
|
1192
1317
|
# Vehicles (Awards)
|
|
1193
1318
|
# ============================================================================
|
|
@@ -1362,7 +1487,17 @@ class TangoClient:
|
|
|
1362
1487
|
flat: bool = False,
|
|
1363
1488
|
flat_lists: bool = False,
|
|
1364
1489
|
search: str | None = None,
|
|
1365
|
-
|
|
1490
|
+
cage_code: str | None = None,
|
|
1491
|
+
naics: str | None = None,
|
|
1492
|
+
name: str | None = None,
|
|
1493
|
+
psc: str | None = None,
|
|
1494
|
+
purpose_of_registration_code: str | None = None,
|
|
1495
|
+
socioeconomic: str | None = None,
|
|
1496
|
+
state: str | None = None,
|
|
1497
|
+
total_awards_obligated_gte: str | None = None,
|
|
1498
|
+
total_awards_obligated_lte: str | None = None,
|
|
1499
|
+
uei: str | None = None,
|
|
1500
|
+
zip_code: str | None = None,
|
|
1366
1501
|
) -> PaginatedResponse:
|
|
1367
1502
|
"""
|
|
1368
1503
|
List entities (vendors/recipients)
|
|
@@ -1373,12 +1508,21 @@ class TangoClient:
|
|
|
1373
1508
|
shape: Response shape string (defaults to minimal shape)
|
|
1374
1509
|
flat: If True, flatten nested objects in shaped response
|
|
1375
1510
|
flat_lists: If True, flatten arrays using indexed keys
|
|
1376
|
-
search: Search query
|
|
1377
|
-
|
|
1511
|
+
search: Search query
|
|
1512
|
+
cage_code: CAGE code filter
|
|
1513
|
+
naics: NAICS code filter
|
|
1514
|
+
name: Entity name filter
|
|
1515
|
+
psc: PSC code filter
|
|
1516
|
+
purpose_of_registration_code: Purpose of registration code
|
|
1517
|
+
socioeconomic: Socioeconomic status filter
|
|
1518
|
+
state: State filter
|
|
1519
|
+
total_awards_obligated_gte: Total awards obligated >=
|
|
1520
|
+
total_awards_obligated_lte: Total awards obligated <=
|
|
1521
|
+
uei: Unique Entity Identifier
|
|
1522
|
+
zip_code: ZIP code filter
|
|
1378
1523
|
"""
|
|
1379
1524
|
params: dict[str, Any] = {"page": page, "limit": min(limit, 100)}
|
|
1380
1525
|
|
|
1381
|
-
# Add shape parameter with default minimal shape
|
|
1382
1526
|
if shape is None:
|
|
1383
1527
|
shape = ShapeConfig.ENTITIES_MINIMAL
|
|
1384
1528
|
if shape:
|
|
@@ -1388,11 +1532,22 @@ class TangoClient:
|
|
|
1388
1532
|
if flat_lists:
|
|
1389
1533
|
params["flat_lists"] = "true"
|
|
1390
1534
|
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1535
|
+
for key, val in (
|
|
1536
|
+
("search", search),
|
|
1537
|
+
("cage_code", cage_code),
|
|
1538
|
+
("naics", naics),
|
|
1539
|
+
("name", name),
|
|
1540
|
+
("psc", psc),
|
|
1541
|
+
("purpose_of_registration_code", purpose_of_registration_code),
|
|
1542
|
+
("socioeconomic", socioeconomic),
|
|
1543
|
+
("state", state),
|
|
1544
|
+
("total_awards_obligated_gte", total_awards_obligated_gte),
|
|
1545
|
+
("total_awards_obligated_lte", total_awards_obligated_lte),
|
|
1546
|
+
("uei", uei),
|
|
1547
|
+
("zip_code", zip_code),
|
|
1548
|
+
):
|
|
1549
|
+
if val is not None:
|
|
1550
|
+
params[key] = val
|
|
1396
1551
|
|
|
1397
1552
|
data = self._get("/api/entities/", params)
|
|
1398
1553
|
|
|
@@ -1442,7 +1597,19 @@ class TangoClient:
|
|
|
1442
1597
|
shape: str | None = None,
|
|
1443
1598
|
flat: bool = False,
|
|
1444
1599
|
flat_lists: bool = False,
|
|
1445
|
-
|
|
1600
|
+
agency: str | None = None,
|
|
1601
|
+
award_date_after: str | None = None,
|
|
1602
|
+
award_date_before: str | None = None,
|
|
1603
|
+
fiscal_year: int | None = None,
|
|
1604
|
+
fiscal_year_gte: int | None = None,
|
|
1605
|
+
fiscal_year_lte: int | None = None,
|
|
1606
|
+
modified_after: str | None = None,
|
|
1607
|
+
modified_before: str | None = None,
|
|
1608
|
+
naics_code: str | None = None,
|
|
1609
|
+
naics_starts_with: str | None = None,
|
|
1610
|
+
search: str | None = None,
|
|
1611
|
+
source_system: str | None = None,
|
|
1612
|
+
status: str | None = None,
|
|
1446
1613
|
) -> PaginatedResponse:
|
|
1447
1614
|
"""
|
|
1448
1615
|
List contract forecasts
|
|
@@ -1453,11 +1620,22 @@ class TangoClient:
|
|
|
1453
1620
|
shape: Response shape string (defaults to minimal shape)
|
|
1454
1621
|
flat: If True, flatten nested objects in shaped response
|
|
1455
1622
|
flat_lists: If True, flatten arrays using indexed keys
|
|
1456
|
-
|
|
1623
|
+
agency: Agency filter
|
|
1624
|
+
award_date_after: Award date after (YYYY-MM-DD)
|
|
1625
|
+
award_date_before: Award date before (YYYY-MM-DD)
|
|
1626
|
+
fiscal_year: Fiscal year (exact match)
|
|
1627
|
+
fiscal_year_gte: Fiscal year >=
|
|
1628
|
+
fiscal_year_lte: Fiscal year <=
|
|
1629
|
+
modified_after: Modified after date
|
|
1630
|
+
modified_before: Modified before date
|
|
1631
|
+
naics_code: NAICS code filter
|
|
1632
|
+
naics_starts_with: NAICS code prefix filter
|
|
1633
|
+
search: Search query
|
|
1634
|
+
source_system: Source system filter
|
|
1635
|
+
status: Status filter
|
|
1457
1636
|
"""
|
|
1458
1637
|
params: dict[str, Any] = {"page": page, "limit": min(limit, 100)}
|
|
1459
1638
|
|
|
1460
|
-
# Add shape parameter with default minimal shape
|
|
1461
1639
|
if shape is None:
|
|
1462
1640
|
shape = ShapeConfig.FORECASTS_MINIMAL
|
|
1463
1641
|
if shape:
|
|
@@ -1467,7 +1645,23 @@ class TangoClient:
|
|
|
1467
1645
|
if flat_lists:
|
|
1468
1646
|
params["flat_lists"] = "true"
|
|
1469
1647
|
|
|
1470
|
-
|
|
1648
|
+
for key, val in (
|
|
1649
|
+
("agency", agency),
|
|
1650
|
+
("award_date_after", award_date_after),
|
|
1651
|
+
("award_date_before", award_date_before),
|
|
1652
|
+
("fiscal_year", fiscal_year),
|
|
1653
|
+
("fiscal_year_gte", fiscal_year_gte),
|
|
1654
|
+
("fiscal_year_lte", fiscal_year_lte),
|
|
1655
|
+
("modified_after", modified_after),
|
|
1656
|
+
("modified_before", modified_before),
|
|
1657
|
+
("naics_code", naics_code),
|
|
1658
|
+
("naics_starts_with", naics_starts_with),
|
|
1659
|
+
("search", search),
|
|
1660
|
+
("source_system", source_system),
|
|
1661
|
+
("status", status),
|
|
1662
|
+
):
|
|
1663
|
+
if val is not None:
|
|
1664
|
+
params[key] = val
|
|
1471
1665
|
|
|
1472
1666
|
data = self._get("/api/forecasts/", params)
|
|
1473
1667
|
|
|
@@ -1492,7 +1686,21 @@ class TangoClient:
|
|
|
1492
1686
|
shape: str | None = None,
|
|
1493
1687
|
flat: bool = False,
|
|
1494
1688
|
flat_lists: bool = False,
|
|
1495
|
-
|
|
1689
|
+
active: bool | None = None,
|
|
1690
|
+
agency: str | None = None,
|
|
1691
|
+
first_notice_date_after: str | None = None,
|
|
1692
|
+
first_notice_date_before: str | None = None,
|
|
1693
|
+
last_notice_date_after: str | None = None,
|
|
1694
|
+
last_notice_date_before: str | None = None,
|
|
1695
|
+
naics: str | None = None,
|
|
1696
|
+
notice_type: str | None = None,
|
|
1697
|
+
place_of_performance: str | None = None,
|
|
1698
|
+
psc: str | None = None,
|
|
1699
|
+
response_deadline_after: str | None = None,
|
|
1700
|
+
response_deadline_before: str | None = None,
|
|
1701
|
+
search: str | None = None,
|
|
1702
|
+
set_aside: str | None = None,
|
|
1703
|
+
solicitation_number: str | None = None,
|
|
1496
1704
|
) -> PaginatedResponse:
|
|
1497
1705
|
"""
|
|
1498
1706
|
List contract opportunities/solicitations
|
|
@@ -1503,11 +1711,24 @@ class TangoClient:
|
|
|
1503
1711
|
shape: Response shape string (defaults to minimal shape)
|
|
1504
1712
|
flat: If True, flatten nested objects in shaped response
|
|
1505
1713
|
flat_lists: If True, flatten arrays using indexed keys
|
|
1506
|
-
|
|
1714
|
+
active: Filter by active status
|
|
1715
|
+
agency: Agency filter
|
|
1716
|
+
first_notice_date_after: First notice date after
|
|
1717
|
+
first_notice_date_before: First notice date before
|
|
1718
|
+
last_notice_date_after: Last notice date after
|
|
1719
|
+
last_notice_date_before: Last notice date before
|
|
1720
|
+
naics: NAICS code filter
|
|
1721
|
+
notice_type: Notice type filter
|
|
1722
|
+
place_of_performance: Place of performance filter
|
|
1723
|
+
psc: PSC code filter
|
|
1724
|
+
response_deadline_after: Response deadline after
|
|
1725
|
+
response_deadline_before: Response deadline before
|
|
1726
|
+
search: Search query
|
|
1727
|
+
set_aside: Set-aside type filter
|
|
1728
|
+
solicitation_number: Solicitation number filter
|
|
1507
1729
|
"""
|
|
1508
1730
|
params: dict[str, Any] = {"page": page, "limit": min(limit, 100)}
|
|
1509
1731
|
|
|
1510
|
-
# Add shape parameter with default minimal shape
|
|
1511
1732
|
if shape is None:
|
|
1512
1733
|
shape = ShapeConfig.OPPORTUNITIES_MINIMAL
|
|
1513
1734
|
if shape:
|
|
@@ -1517,7 +1738,25 @@ class TangoClient:
|
|
|
1517
1738
|
if flat_lists:
|
|
1518
1739
|
params["flat_lists"] = "true"
|
|
1519
1740
|
|
|
1520
|
-
|
|
1741
|
+
for key, val in (
|
|
1742
|
+
("active", active),
|
|
1743
|
+
("agency", agency),
|
|
1744
|
+
("first_notice_date_after", first_notice_date_after),
|
|
1745
|
+
("first_notice_date_before", first_notice_date_before),
|
|
1746
|
+
("last_notice_date_after", last_notice_date_after),
|
|
1747
|
+
("last_notice_date_before", last_notice_date_before),
|
|
1748
|
+
("naics", naics),
|
|
1749
|
+
("notice_type", notice_type),
|
|
1750
|
+
("place_of_performance", place_of_performance),
|
|
1751
|
+
("psc", psc),
|
|
1752
|
+
("response_deadline_after", response_deadline_after),
|
|
1753
|
+
("response_deadline_before", response_deadline_before),
|
|
1754
|
+
("search", search),
|
|
1755
|
+
("set_aside", set_aside),
|
|
1756
|
+
("solicitation_number", solicitation_number),
|
|
1757
|
+
):
|
|
1758
|
+
if val is not None:
|
|
1759
|
+
params[key] = val
|
|
1521
1760
|
|
|
1522
1761
|
data = self._get("/api/opportunities/", params)
|
|
1523
1762
|
|
|
@@ -1542,7 +1781,18 @@ class TangoClient:
|
|
|
1542
1781
|
shape: str | None = None,
|
|
1543
1782
|
flat: bool = False,
|
|
1544
1783
|
flat_lists: bool = False,
|
|
1545
|
-
|
|
1784
|
+
active: bool | None = None,
|
|
1785
|
+
agency: str | None = None,
|
|
1786
|
+
naics: str | None = None,
|
|
1787
|
+
notice_type: str | None = None,
|
|
1788
|
+
posted_date_after: str | None = None,
|
|
1789
|
+
posted_date_before: str | None = None,
|
|
1790
|
+
psc: str | None = None,
|
|
1791
|
+
response_deadline_after: str | None = None,
|
|
1792
|
+
response_deadline_before: str | None = None,
|
|
1793
|
+
search: str | None = None,
|
|
1794
|
+
set_aside: str | None = None,
|
|
1795
|
+
solicitation_number: str | None = None,
|
|
1546
1796
|
) -> PaginatedResponse:
|
|
1547
1797
|
"""
|
|
1548
1798
|
List contract notices
|
|
@@ -1550,16 +1800,24 @@ class TangoClient:
|
|
|
1550
1800
|
Args:
|
|
1551
1801
|
page: Page number
|
|
1552
1802
|
limit: Results per page (max 100)
|
|
1553
|
-
shape: Response shape string (defaults to minimal shape)
|
|
1554
|
-
Use None to disable shaping, ShapeConfig.NOTICES_MINIMAL for minimal,
|
|
1555
|
-
or provide custom shape string
|
|
1803
|
+
shape: Response shape string (defaults to minimal shape)
|
|
1556
1804
|
flat: If True, flatten nested objects in shaped response
|
|
1557
1805
|
flat_lists: If True, flatten arrays using indexed keys
|
|
1558
|
-
|
|
1806
|
+
active: Filter by active status
|
|
1807
|
+
agency: Agency filter
|
|
1808
|
+
naics: NAICS code filter
|
|
1809
|
+
notice_type: Notice type filter
|
|
1810
|
+
posted_date_after: Posted date after
|
|
1811
|
+
posted_date_before: Posted date before
|
|
1812
|
+
psc: PSC code filter
|
|
1813
|
+
response_deadline_after: Response deadline after
|
|
1814
|
+
response_deadline_before: Response deadline before
|
|
1815
|
+
search: Search query
|
|
1816
|
+
set_aside: Set-aside type filter
|
|
1817
|
+
solicitation_number: Solicitation number filter
|
|
1559
1818
|
"""
|
|
1560
1819
|
params: dict[str, Any] = {"page": page, "limit": min(limit, 100)}
|
|
1561
1820
|
|
|
1562
|
-
# Add shape parameter with default minimal shape
|
|
1563
1821
|
if shape is None:
|
|
1564
1822
|
shape = ShapeConfig.NOTICES_MINIMAL
|
|
1565
1823
|
if shape:
|
|
@@ -1569,7 +1827,22 @@ class TangoClient:
|
|
|
1569
1827
|
if flat_lists:
|
|
1570
1828
|
params["flat_lists"] = "true"
|
|
1571
1829
|
|
|
1572
|
-
|
|
1830
|
+
for key, val in (
|
|
1831
|
+
("active", active),
|
|
1832
|
+
("agency", agency),
|
|
1833
|
+
("naics", naics),
|
|
1834
|
+
("notice_type", notice_type),
|
|
1835
|
+
("posted_date_after", posted_date_after),
|
|
1836
|
+
("posted_date_before", posted_date_before),
|
|
1837
|
+
("psc", psc),
|
|
1838
|
+
("response_deadline_after", response_deadline_after),
|
|
1839
|
+
("response_deadline_before", response_deadline_before),
|
|
1840
|
+
("search", search),
|
|
1841
|
+
("set_aside", set_aside),
|
|
1842
|
+
("solicitation_number", solicitation_number),
|
|
1843
|
+
):
|
|
1844
|
+
if val is not None:
|
|
1845
|
+
params[key] = val
|
|
1573
1846
|
|
|
1574
1847
|
data = self._get("/api/notices/", params)
|
|
1575
1848
|
|
|
@@ -1594,7 +1867,18 @@ class TangoClient:
|
|
|
1594
1867
|
shape: str | None = None,
|
|
1595
1868
|
flat: bool = False,
|
|
1596
1869
|
flat_lists: bool = False,
|
|
1597
|
-
|
|
1870
|
+
agency: str | None = None,
|
|
1871
|
+
applicant_types: str | None = None,
|
|
1872
|
+
cfda_number: str | None = None,
|
|
1873
|
+
funding_categories: str | None = None,
|
|
1874
|
+
funding_instruments: str | None = None,
|
|
1875
|
+
opportunity_number: str | None = None,
|
|
1876
|
+
posted_date_after: str | None = None,
|
|
1877
|
+
posted_date_before: str | None = None,
|
|
1878
|
+
response_date_after: str | None = None,
|
|
1879
|
+
response_date_before: str | None = None,
|
|
1880
|
+
search: str | None = None,
|
|
1881
|
+
status: str | None = None,
|
|
1598
1882
|
) -> PaginatedResponse:
|
|
1599
1883
|
"""
|
|
1600
1884
|
List grants
|
|
@@ -1602,16 +1886,24 @@ class TangoClient:
|
|
|
1602
1886
|
Args:
|
|
1603
1887
|
page: Page number
|
|
1604
1888
|
limit: Results per page (max 100)
|
|
1605
|
-
shape: Response shape string (defaults to minimal shape)
|
|
1606
|
-
Use None to disable shaping, ShapeConfig.GRANTS_MINIMAL for minimal,
|
|
1607
|
-
or provide custom shape string
|
|
1889
|
+
shape: Response shape string (defaults to minimal shape)
|
|
1608
1890
|
flat: If True, flatten nested objects in shaped response
|
|
1609
1891
|
flat_lists: If True, flatten arrays using indexed keys
|
|
1610
|
-
|
|
1892
|
+
agency: Agency filter
|
|
1893
|
+
applicant_types: Applicant types filter
|
|
1894
|
+
cfda_number: CFDA number filter
|
|
1895
|
+
funding_categories: Funding categories filter
|
|
1896
|
+
funding_instruments: Funding instruments filter
|
|
1897
|
+
opportunity_number: Opportunity number filter
|
|
1898
|
+
posted_date_after: Posted date after
|
|
1899
|
+
posted_date_before: Posted date before
|
|
1900
|
+
response_date_after: Response date after
|
|
1901
|
+
response_date_before: Response date before
|
|
1902
|
+
search: Search query
|
|
1903
|
+
status: Status filter
|
|
1611
1904
|
"""
|
|
1612
1905
|
params: dict[str, Any] = {"page": page, "limit": min(limit, 100)}
|
|
1613
1906
|
|
|
1614
|
-
# Add shape parameter with default minimal shape
|
|
1615
1907
|
if shape is None:
|
|
1616
1908
|
shape = ShapeConfig.GRANTS_MINIMAL
|
|
1617
1909
|
if shape:
|
|
@@ -1621,7 +1913,22 @@ class TangoClient:
|
|
|
1621
1913
|
if flat_lists:
|
|
1622
1914
|
params["flat_lists"] = "true"
|
|
1623
1915
|
|
|
1624
|
-
|
|
1916
|
+
for key, val in (
|
|
1917
|
+
("agency", agency),
|
|
1918
|
+
("applicant_types", applicant_types),
|
|
1919
|
+
("cfda_number", cfda_number),
|
|
1920
|
+
("funding_categories", funding_categories),
|
|
1921
|
+
("funding_instruments", funding_instruments),
|
|
1922
|
+
("opportunity_number", opportunity_number),
|
|
1923
|
+
("posted_date_after", posted_date_after),
|
|
1924
|
+
("posted_date_before", posted_date_before),
|
|
1925
|
+
("response_date_after", response_date_after),
|
|
1926
|
+
("response_date_before", response_date_before),
|
|
1927
|
+
("search", search),
|
|
1928
|
+
("status", status),
|
|
1929
|
+
):
|
|
1930
|
+
if val is not None:
|
|
1931
|
+
params[key] = val
|
|
1625
1932
|
|
|
1626
1933
|
data = self._get("/api/grants/", params)
|
|
1627
1934
|
|
tango/models.py
CHANGED
|
@@ -339,6 +339,19 @@ class Subaward:
|
|
|
339
339
|
amount: Decimal | None = None
|
|
340
340
|
|
|
341
341
|
|
|
342
|
+
@dataclass
|
|
343
|
+
class GsaElibraryContract:
|
|
344
|
+
"""Schema definition for GSA eLibrary Contract (not used for instances)"""
|
|
345
|
+
|
|
346
|
+
uuid: str
|
|
347
|
+
contract_number: str | None = None
|
|
348
|
+
schedule: str | None = None
|
|
349
|
+
cooperative_purchasing: bool | None = None
|
|
350
|
+
disaster_recovery_purchasing: bool | None = None
|
|
351
|
+
file_urls: list[str] | None = None
|
|
352
|
+
sins: list[str] | None = None
|
|
353
|
+
|
|
354
|
+
|
|
342
355
|
@dataclass
|
|
343
356
|
class Vehicle:
|
|
344
357
|
"""Schema definition for Vehicle (not used for instances)"""
|
|
@@ -624,3 +637,8 @@ class ShapeConfig:
|
|
|
624
637
|
SUBAWARDS_MINIMAL: Final = (
|
|
625
638
|
"award_key,prime_recipient(uei,display_name),subaward_recipient(uei,display_name)"
|
|
626
639
|
)
|
|
640
|
+
|
|
641
|
+
# Default for list_gsa_elibrary_contracts()
|
|
642
|
+
GSA_ELIBRARY_CONTRACTS_MINIMAL: Final = (
|
|
643
|
+
"uuid,contract_number,schedule,recipient(display_name,uei),idv(key,award_date)"
|
|
644
|
+
)
|
tango/shapes/explicit_schemas.py
CHANGED
|
@@ -1045,6 +1045,42 @@ SUBAWARD_SCHEMA: dict[str, FieldSchema] = {
|
|
|
1045
1045
|
),
|
|
1046
1046
|
}
|
|
1047
1047
|
|
|
1048
|
+
# GSA eLibrary Contract
|
|
1049
|
+
GSA_ELIBRARY_IDV_REF_SCHEMA: dict[str, FieldSchema] = {
|
|
1050
|
+
"key": FieldSchema(name="key", type=str, is_optional=True, is_list=False),
|
|
1051
|
+
"award_date": FieldSchema(name="award_date", type=date, is_optional=True, is_list=False),
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
GSA_ELIBRARY_CONTRACT_SCHEMA: dict[str, FieldSchema] = {
|
|
1055
|
+
"uuid": FieldSchema(name="uuid", type=str, is_optional=False, is_list=False),
|
|
1056
|
+
"contract_number": FieldSchema(
|
|
1057
|
+
name="contract_number", type=str, is_optional=True, is_list=False
|
|
1058
|
+
),
|
|
1059
|
+
"cooperative_purchasing": FieldSchema(
|
|
1060
|
+
name="cooperative_purchasing", type=bool, is_optional=True, is_list=False
|
|
1061
|
+
),
|
|
1062
|
+
"disaster_recovery_purchasing": FieldSchema(
|
|
1063
|
+
name="disaster_recovery_purchasing", type=bool, is_optional=True, is_list=False
|
|
1064
|
+
),
|
|
1065
|
+
"file_urls": FieldSchema(name="file_urls", type=list, is_optional=True, is_list=True),
|
|
1066
|
+
"schedule": FieldSchema(name="schedule", type=str, is_optional=True, is_list=False),
|
|
1067
|
+
"sins": FieldSchema(name="sins", type=list, is_optional=True, is_list=True),
|
|
1068
|
+
"idv": FieldSchema(
|
|
1069
|
+
name="idv",
|
|
1070
|
+
type=dict,
|
|
1071
|
+
is_optional=True,
|
|
1072
|
+
is_list=False,
|
|
1073
|
+
nested_model="GsaElibraryIdvRef",
|
|
1074
|
+
),
|
|
1075
|
+
"recipient": FieldSchema(
|
|
1076
|
+
name="recipient",
|
|
1077
|
+
type=dict,
|
|
1078
|
+
is_optional=True,
|
|
1079
|
+
is_list=False,
|
|
1080
|
+
nested_model="RecipientProfile",
|
|
1081
|
+
),
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1048
1084
|
# ============================================================================
|
|
1049
1085
|
# SCHEMA REGISTRY MAPPING
|
|
1050
1086
|
# ============================================================================
|
|
@@ -1084,6 +1120,9 @@ EXPLICIT_SCHEMAS: dict[str, dict[str, FieldSchema]] = {
|
|
|
1084
1120
|
"OTA": OTA_SCHEMA,
|
|
1085
1121
|
"OTIDV": OTIDV_SCHEMA,
|
|
1086
1122
|
"Subaward": SUBAWARD_SCHEMA,
|
|
1123
|
+
# GSA eLibrary
|
|
1124
|
+
"GsaElibraryContract": GSA_ELIBRARY_CONTRACT_SCHEMA,
|
|
1125
|
+
"GsaElibraryIdvRef": GSA_ELIBRARY_IDV_REF_SCHEMA,
|
|
1087
1126
|
}
|
|
1088
1127
|
|
|
1089
1128
|
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
tango/__init__.py,sha256=
|
|
2
|
-
tango/client.py,sha256=
|
|
1
|
+
tango/__init__.py,sha256=7EdEUgCcK0lDNJWWDgdSWxx8xxryO-fHL-iml9PaYLw,1102
|
|
2
|
+
tango/client.py,sha256=ykeTSh4rI4P3LZFALLfGkl2Yr6jM7NWrq_E4V5vY0nc,84112
|
|
3
3
|
tango/exceptions.py,sha256=JmtbOY0ofBnX24pUErh2XFlTj9dim2ngyboserEGRFw,2226
|
|
4
|
-
tango/models.py,sha256=
|
|
4
|
+
tango/models.py,sha256=E5jbcQ1CHevTJBD1KOREAqql9bTkft91WaNsL8qbnuA,19575
|
|
5
5
|
tango/shapes/__init__.py,sha256=7ea1WU74jp4znhNw-gXruag6m6eyPZtbVgbDFmFUWro,1072
|
|
6
|
-
tango/shapes/explicit_schemas.py,sha256=
|
|
6
|
+
tango/shapes/explicit_schemas.py,sha256=iKvmpmeFU8pr4PpTenlpXDKxNbLkuyfUdDc8IV7p4zk,51734
|
|
7
7
|
tango/shapes/factory.py,sha256=ytpMi5Uw72XZ8MimhuSsLDVXF3zO_Zt3_tAL6NF7LnU,34318
|
|
8
8
|
tango/shapes/generator.py,sha256=61V1T3lm8Ps_KSMJAezQJLQVFbNKt1jtoLyhiqNtFTs,23380
|
|
9
9
|
tango/shapes/models.py,sha256=h3pIhOqrrdlN953Y6r0oney5HFbKPOD-frRndRWimJ0,3018
|
|
10
10
|
tango/shapes/parser.py,sha256=k6OsI2w3GH6-IBbc-XTLgL1mWH7bMf7A_dA6pr1xKfw,24619
|
|
11
11
|
tango/shapes/schema.py,sha256=VRPOB1sBdjFyimNchrZKIpTHn83CyX4RfU9077aQtIU,14136
|
|
12
12
|
tango/shapes/types.py,sha256=27jrAE0VIdrKaLjR_FK71hfIIGX2Tg3ex7REEBV1TFE,1301
|
|
13
|
-
tango_python-0.4.
|
|
14
|
-
tango_python-0.4.
|
|
15
|
-
tango_python-0.4.
|
|
16
|
-
tango_python-0.4.
|
|
13
|
+
tango_python-0.4.1.dist-info/METADATA,sha256=QTa_gFDGAc9jj23jv35_0Zy9Js3bXlzK6FV-9OnjLFg,16210
|
|
14
|
+
tango_python-0.4.1.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
15
|
+
tango_python-0.4.1.dist-info/licenses/LICENSE,sha256=j2kYVHMwTkoGn3ZNScnrdIueG0k2XzB_LCPFoyBc2wk,1064
|
|
16
|
+
tango_python-0.4.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|