Skip to content

Commit a56fa0e

Browse files
authored
Fixed the opportunities search (#25)
* Fixed the opportunities search * Bumped the version
1 parent 155a2c9 commit a56fa0e

File tree

4 files changed

+43
-23
lines changed

4 files changed

+43
-23
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "procurement-tools"
3-
version = "0.2.1"
3+
version = "0.2.2"
44
description = "Python tools for navigating federal contracting"
55
authors = ["V. David Zvenyach <dave@tandemgov.com>"]
66
readme = "README.md"

src/procurement_tools/cli/main.py

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,23 @@ def entity(uei: str):
3535
def opportunities(
3636
*,
3737
q: str = "",
38-
postedFrom: Optional[
39-
str
40-
] = None, # (datetime.now() - timedelta(days=364)).strftime("%Y-%m-%d"),
41-
postedTo: Optional[str] = None, # datetime.now().strftime("%Y-%m-%d"),
38+
updatedFrom: Optional[str] = None,
39+
updatedTo: Optional[str] = None,
4240
active: str = "true",
4341
mode: str = "ALL",
42+
notice_type: Optional[str] = None
4443
):
4544
"""Get SAM opportunities' JSON data"""
46-
params = {
47-
"q": q,
48-
"active": active,
49-
"mode": mode,
50-
}
51-
if postedFrom:
52-
params["modified_date.from"] = (postedFrom + "-06:00",)
53-
if postedTo:
54-
params["modified_date.to"] = (postedTo + "-06:00",)
55-
56-
res = SAM.get_opportunities(params)
45+
res = SAM.get_opportunities(
46+
dict(
47+
q=q,
48+
is_active=active,
49+
mode=mode,
50+
postedFrom=updatedFrom,
51+
postedTo=updatedTo,
52+
notice_type=notice_type,
53+
)
54+
)
5755
print(json.dumps(res))
5856

5957

src/procurement_tools/models/opportunities.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,21 @@ class SetAsideEnum(str, Enum):
4242
vss = "Veteran-Owned Small Business Sole source (specific to Department of Veterans Affairs)"
4343

4444

45+
class modeEnum(str, Enum):
46+
any_mode = "ANY"
47+
exact_mode = "EXACT"
48+
all_mode = "ALL"
49+
50+
4551
class OpportunitiesRequestParams(BaseModel):
52+
q: str = None
53+
is_active: str = Field(default="true", alias="active")
54+
qMode: modeEnum = Field(default="ALL", description="query mode", alias="q_mode")
55+
postedFrom: Optional[str]
56+
postedTo: Optional[str]
57+
58+
59+
class APIOpportunitiesRequestParams(BaseModel):
4660
ptype: Optional[PtypeEnum] = None
4761
solnum: Optional[str] = Field(description="Solicitation Number", default=None)
4862
noticeid: Optional[str] = Field(description="Notice ID", default=None)

src/procurement_tools/sam.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
from .models.entity import Entity
2-
from .models.opportunities import OpportunitiesRequestParams
2+
from .models.opportunities import (
3+
OpportunitiesRequestParams,
4+
APIOpportunitiesRequestParams,
5+
)
36
from .uei import UEI
47
from datetime import date, timedelta
58
import httpx
@@ -96,10 +99,15 @@ def get_opportunities(params: dict) -> dict:
9699
seed = "".join(choice(digits) for i in range(13))
97100
mode = params.get("mode", "ALL")
98101
active = params.get("active", "true")
99-
BASE_URL = f"https://sam.gov/api/prod/sgs/v1/search/?random={seed}&index=opp&page=0&sort=-modifiedDate&size=1000&mode=search&responseType=json&qMode={mode}&is_active={active}"
100-
101-
param_str = urlencode(params)
102-
url = f"{BASE_URL}&{param_str}"
102+
url = f"https://sam.gov/api/prod/sgs/v1/search/?random={seed}&index=opp&page=0&sort=-modifiedDate&size=1000&mode=search&responseType=json&qMode={mode}&is_active={active}"
103+
104+
if mod_from_date := params.get("postedFrom"):
105+
url += f"&modified_date.from={mod_from_date}-06:00"
106+
if mod_to_date := params.get("postedTo"):
107+
url += f"&modified_date.from={mod_to_date}-06:00"
108+
url += f"&q={params.get('q')}"
109+
if notice_type := params.get("notice_type"):
110+
url += f"&notice_type={notice_type}"
103111
res = httpx.get(url)
104112
data = res.json()
105113
return data
@@ -114,14 +122,14 @@ def get_api_opportunities(params: dict) -> dict:
114122
115123
Args:
116124
params: A dict for the request parameters to the SAM API. As currently implemented, we use \
117-
OpportunitiesRequestParams to check whether the parameters are valid.
125+
APIOpportunitiesRequestParams to check whether the parameters are valid.
118126
119127
Returns:
120128
A dict
121129
"""
122130

123131
try:
124-
request_params = OpportunitiesRequestParams(**params).model_dump(
132+
request_params = APIOpportunitiesRequestParams(**params).model_dump(
125133
exclude_none=True
126134
)
127135
except ValidationError:

0 commit comments

Comments
 (0)