phactor 0.3.2__tar.gz → 0.4.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.
- {phactor-0.3.2 → phactor-0.4.0}/CHANGELOG.md +22 -0
- {phactor-0.3.2 → phactor-0.4.0}/PKG-INFO +55 -1
- {phactor-0.3.2 → phactor-0.4.0}/README.md +54 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/__init__.py +12 -0
- phactor-0.4.0/src/phactor/_version.py +1 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/cohorts/client.py +5 -1
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/cohorts/models.py +69 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/cohorts/query.py +8 -0
- phactor-0.3.2/src/phactor/_version.py +0 -1
- {phactor-0.3.2 → phactor-0.4.0}/.gitignore +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/LICENSE +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/pyproject.toml +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/_graphql.py +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/_http.py +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/auth.py +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/client.py +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/cohorts/__init__.py +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/cohorts/builder.py +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/config.py +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/exceptions.py +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/pandas.py +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/py.typed +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/sites/__init__.py +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/sites/client.py +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/sites/models.py +0 -0
- {phactor-0.3.2 → phactor-0.4.0}/src/phactor/sites/query.py +0 -0
|
@@ -6,6 +6,28 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
While the SDK is pre-1.0 (`0.x`), breaking changes may accompany a minor version bump.
|
|
8
8
|
|
|
9
|
+
## [0.4.0] - 2026-10-06
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Nearby provider sites.** A `PROXIMITY` grouping can set
|
|
14
|
+
`"includeNearbyProviderSites": True` (`GroupingInput.include_nearby_provider_sites`)
|
|
15
|
+
to also get your subscribed providers' sites inside each radius or distance
|
|
16
|
+
band. The result is `AnalyzeCohortsPayload.nearby_provider_sites`, `None`
|
|
17
|
+
when not requested.
|
|
18
|
+
- New models `NearbyProviderSites` (`status`, `truncated`, `sites`),
|
|
19
|
+
`NearbyProviderSite` (address, coordinates, `providers`, `matches`),
|
|
20
|
+
`NearbyProviderRef` (`id`, `name`, `provider_type`, `color`) and
|
|
21
|
+
`NearbyProviderSiteMatch` (`site_name`, coordinates, `distance_miles`).
|
|
22
|
+
- New enums `NearbyProviderSitesStatus` (`AVAILABLE`, `UNAVAILABLE`) and
|
|
23
|
+
`DataProviderType`. Like the 0.3.2 response enums, an unknown value from
|
|
24
|
+
the API is kept as a plain string.
|
|
25
|
+
- At most 500 sites are returned, nearest first; `truncated` is `True` when
|
|
26
|
+
more matched.
|
|
27
|
+
- With the option on, the server rejects the request (`GraphQLError`) when it
|
|
28
|
+
has more than 50 distinct providers, more than 25 grouping sites, or a radius
|
|
29
|
+
or distance band outside 1-250 miles. Without it these limits do not apply.
|
|
30
|
+
|
|
9
31
|
## [0.3.2] - 2026-09-24
|
|
10
32
|
|
|
11
33
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: phactor
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Python SDK for the Phactor clinical trial feasibility platform
|
|
5
5
|
Project-URL: Homepage, https://phactor.ai
|
|
6
6
|
Project-URL: Documentation, https://docs.phactor.ai
|
|
@@ -282,3 +282,57 @@ There are three independent operator levels:
|
|
|
282
282
|
Exclusion groups are always unioned and subtracted from the pathway's combined
|
|
283
283
|
inclusion result. For example, an `OR` pathway with inclusion groups `A` and `B`
|
|
284
284
|
and exclusion group `E` evaluates as `(A OR B) EXCEPT E`.
|
|
285
|
+
|
|
286
|
+
## Geographic Grouping
|
|
287
|
+
|
|
288
|
+
Group cohort results by geography using PROXIMITY and RADIUS or DISTANCE_BANDS mode:
|
|
289
|
+
|
|
290
|
+
```python
|
|
291
|
+
result = client.cohorts.analyze(
|
|
292
|
+
providers=[...],
|
|
293
|
+
cohort_groups=[...],
|
|
294
|
+
grouping={
|
|
295
|
+
"type": "PROXIMITY",
|
|
296
|
+
"proximityMode": "RADIUS",
|
|
297
|
+
"sites": [
|
|
298
|
+
{"name": "Johns Hopkins", "latitude": 39.2963, "longitude": -76.5927, "radiusMiles": 25}
|
|
299
|
+
],
|
|
300
|
+
},
|
|
301
|
+
)
|
|
302
|
+
for analysis in result.analyses:
|
|
303
|
+
for group in analysis.site_radius_results or []:
|
|
304
|
+
print(group.site_name, group.count, group.percentage)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Provider sites near each grouping site
|
|
308
|
+
|
|
309
|
+
```python
|
|
310
|
+
from phactor import NearbyProviderSitesStatus
|
|
311
|
+
|
|
312
|
+
result = client.cohorts.analyze(
|
|
313
|
+
providers=[...],
|
|
314
|
+
cohort_groups=[...],
|
|
315
|
+
grouping={
|
|
316
|
+
"type": "PROXIMITY",
|
|
317
|
+
"proximityMode": "RADIUS",
|
|
318
|
+
"sites": [
|
|
319
|
+
{"name": "Johns Hopkins", "latitude": 39.2963, "longitude": -76.5927, "radiusMiles": 25}
|
|
320
|
+
],
|
|
321
|
+
"includeNearbyProviderSites": True,
|
|
322
|
+
},
|
|
323
|
+
)
|
|
324
|
+
nearby = result.nearby_provider_sites
|
|
325
|
+
if nearby and nearby.status == NearbyProviderSitesStatus.AVAILABLE:
|
|
326
|
+
for site in nearby.sites:
|
|
327
|
+
print(site.name, [p.name for p in site.providers], [m.distance_miles for m in site.matches])
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Only sites of subscribed providers you included in `providers` are returned. Each provider
|
|
331
|
+
carries its `provider_type` (a `DataProviderType`) and its display `color` (`#rrggbb`).
|
|
332
|
+
`NearbyProviderSitesStatus.UNAVAILABLE` means the site lookup failed; the cohort counts are
|
|
333
|
+
still valid. At most the nearest 500 sites are returned; `truncated` is `True` when there were
|
|
334
|
+
more.
|
|
335
|
+
|
|
336
|
+
With `includeNearbyProviderSites` on, the request is rejected with a `GraphQLError` when it has
|
|
337
|
+
more than 50 distinct providers, more than 25 grouping sites, or a radius or distance band outside
|
|
338
|
+
1-250 miles.
|
|
@@ -243,3 +243,57 @@ There are three independent operator levels:
|
|
|
243
243
|
Exclusion groups are always unioned and subtracted from the pathway's combined
|
|
244
244
|
inclusion result. For example, an `OR` pathway with inclusion groups `A` and `B`
|
|
245
245
|
and exclusion group `E` evaluates as `(A OR B) EXCEPT E`.
|
|
246
|
+
|
|
247
|
+
## Geographic Grouping
|
|
248
|
+
|
|
249
|
+
Group cohort results by geography using PROXIMITY and RADIUS or DISTANCE_BANDS mode:
|
|
250
|
+
|
|
251
|
+
```python
|
|
252
|
+
result = client.cohorts.analyze(
|
|
253
|
+
providers=[...],
|
|
254
|
+
cohort_groups=[...],
|
|
255
|
+
grouping={
|
|
256
|
+
"type": "PROXIMITY",
|
|
257
|
+
"proximityMode": "RADIUS",
|
|
258
|
+
"sites": [
|
|
259
|
+
{"name": "Johns Hopkins", "latitude": 39.2963, "longitude": -76.5927, "radiusMiles": 25}
|
|
260
|
+
],
|
|
261
|
+
},
|
|
262
|
+
)
|
|
263
|
+
for analysis in result.analyses:
|
|
264
|
+
for group in analysis.site_radius_results or []:
|
|
265
|
+
print(group.site_name, group.count, group.percentage)
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Provider sites near each grouping site
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
from phactor import NearbyProviderSitesStatus
|
|
272
|
+
|
|
273
|
+
result = client.cohorts.analyze(
|
|
274
|
+
providers=[...],
|
|
275
|
+
cohort_groups=[...],
|
|
276
|
+
grouping={
|
|
277
|
+
"type": "PROXIMITY",
|
|
278
|
+
"proximityMode": "RADIUS",
|
|
279
|
+
"sites": [
|
|
280
|
+
{"name": "Johns Hopkins", "latitude": 39.2963, "longitude": -76.5927, "radiusMiles": 25}
|
|
281
|
+
],
|
|
282
|
+
"includeNearbyProviderSites": True,
|
|
283
|
+
},
|
|
284
|
+
)
|
|
285
|
+
nearby = result.nearby_provider_sites
|
|
286
|
+
if nearby and nearby.status == NearbyProviderSitesStatus.AVAILABLE:
|
|
287
|
+
for site in nearby.sites:
|
|
288
|
+
print(site.name, [p.name for p in site.providers], [m.distance_miles for m in site.matches])
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Only sites of subscribed providers you included in `providers` are returned. Each provider
|
|
292
|
+
carries its `provider_type` (a `DataProviderType`) and its display `color` (`#rrggbb`).
|
|
293
|
+
`NearbyProviderSitesStatus.UNAVAILABLE` means the site lookup failed; the cohort counts are
|
|
294
|
+
still valid. At most the nearest 500 sites are returned; `truncated` is `True` when there were
|
|
295
|
+
more.
|
|
296
|
+
|
|
297
|
+
With `includeNearbyProviderSites` on, the request is rejected with a `GraphQLError` when it has
|
|
298
|
+
more than 50 distinct providers, more than 25 grouping sites, or a radius or distance band outside
|
|
299
|
+
1-250 miles.
|
|
@@ -30,6 +30,7 @@ from phactor.cohorts.models import (
|
|
|
30
30
|
CriterionError,
|
|
31
31
|
CriterionErrorDomain,
|
|
32
32
|
CriterionErrorReason,
|
|
33
|
+
DataProviderType,
|
|
33
34
|
DistanceBand,
|
|
34
35
|
GenderValue,
|
|
35
36
|
GeographicGroup,
|
|
@@ -48,6 +49,11 @@ from phactor.cohorts.models import (
|
|
|
48
49
|
MedicationsInput,
|
|
49
50
|
MedicationStatus,
|
|
50
51
|
MedicationTypeEnum,
|
|
52
|
+
NearbyProviderRef,
|
|
53
|
+
NearbyProviderSite,
|
|
54
|
+
NearbyProviderSiteMatch,
|
|
55
|
+
NearbyProviderSites,
|
|
56
|
+
NearbyProviderSitesStatus,
|
|
51
57
|
PdcFilterInput,
|
|
52
58
|
ProcedureInput,
|
|
53
59
|
ProcedureOutcome,
|
|
@@ -113,6 +119,8 @@ __all__ = [
|
|
|
113
119
|
"CriterionErrorReason",
|
|
114
120
|
"ResultGrouping",
|
|
115
121
|
"ProximityMode",
|
|
122
|
+
"NearbyProviderSitesStatus",
|
|
123
|
+
"DataProviderType",
|
|
116
124
|
# Input models
|
|
117
125
|
"TimingInput",
|
|
118
126
|
"AgeRangeInput",
|
|
@@ -148,6 +156,10 @@ __all__ = [
|
|
|
148
156
|
"CriterionError",
|
|
149
157
|
"DistanceBand",
|
|
150
158
|
"GeographicGroup",
|
|
159
|
+
"NearbyProviderRef",
|
|
160
|
+
"NearbyProviderSite",
|
|
161
|
+
"NearbyProviderSiteMatch",
|
|
162
|
+
"NearbyProviderSites",
|
|
151
163
|
"SiteDistanceBandResult",
|
|
152
164
|
"SiteRadiusResult",
|
|
153
165
|
# Site search
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.4.0"
|
|
@@ -156,7 +156,11 @@ class CohortsClient:
|
|
|
156
156
|
age_buckets: Custom age range buckets for demographic breakdown.
|
|
157
157
|
include_combined_demographic_breakdown:
|
|
158
158
|
Include combined-population demographic breakdown.
|
|
159
|
-
grouping: Geographic grouping configuration dict.
|
|
159
|
+
grouping: Geographic grouping configuration dict. With
|
|
160
|
+
``includeNearbyProviderSites`` on, the server rejects the request
|
|
161
|
+
(``GraphQLError``) when it has more than 50 distinct providers,
|
|
162
|
+
more than 25 grouping sites, or a radius or distance band outside
|
|
163
|
+
1-250 miles.
|
|
160
164
|
global_filters: Optional global filters applied to all cohort groups
|
|
161
165
|
(e.g. restrict the study to specific states or geographies).
|
|
162
166
|
Returns:
|
|
@@ -608,6 +608,9 @@ class GroupingInput(BaseModel):
|
|
|
608
608
|
# Opt-in exact radius / distance-band counts (PostGIS ST_DWithin
|
|
609
609
|
# refine over the approximate H3 hex cover). Default None (approximate).
|
|
610
610
|
exact: bool | None = None
|
|
611
|
+
# Opt-in: also return subscribed providers' sites inside each grouping radius
|
|
612
|
+
# (AnalyzeCohortsPayload.nearby_provider_sites). PROXIMITY only.
|
|
613
|
+
include_nearby_provider_sites: bool | None = None
|
|
611
614
|
|
|
612
615
|
|
|
613
616
|
class GlobalFiltersInput(BaseModel):
|
|
@@ -773,9 +776,75 @@ class ProviderCohortAnalysis(BaseModel):
|
|
|
773
776
|
site_distance_band_results: list[SiteDistanceBandResult] | None = None
|
|
774
777
|
|
|
775
778
|
|
|
779
|
+
class NearbyProviderSitesStatus(str, Enum):
|
|
780
|
+
"""Whether the nearby provider site lookup succeeded. Values the server adds
|
|
781
|
+
later reach ``NearbyProviderSites.status`` as plain strings instead of failing."""
|
|
782
|
+
|
|
783
|
+
AVAILABLE = "AVAILABLE"
|
|
784
|
+
UNAVAILABLE = "UNAVAILABLE"
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
class DataProviderType(str, Enum):
|
|
788
|
+
"""The kind of data a provider holds. Values the server adds later reach
|
|
789
|
+
``NearbyProviderRef.provider_type`` as plain strings instead of failing."""
|
|
790
|
+
|
|
791
|
+
PHARMACY = "PHARMACY"
|
|
792
|
+
HOSPITAL = "HOSPITAL"
|
|
793
|
+
LABORATORY = "LABORATORY"
|
|
794
|
+
EHR_SYSTEM = "EHR_SYSTEM"
|
|
795
|
+
CLAIMS = "CLAIMS"
|
|
796
|
+
GENOMICS = "GENOMICS"
|
|
797
|
+
OTHER = "OTHER"
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
class NearbyProviderRef(BaseModel):
|
|
801
|
+
model_config = _MODEL_CONFIG
|
|
802
|
+
|
|
803
|
+
id: str
|
|
804
|
+
name: str
|
|
805
|
+
# A value this SDK version does not know yet stays a plain string.
|
|
806
|
+
provider_type: DataProviderType | str = Field(union_mode="left_to_right")
|
|
807
|
+
# The provider's display color as a ``#rrggbb`` hex string.
|
|
808
|
+
color: str
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
class NearbyProviderSiteMatch(BaseModel):
|
|
812
|
+
model_config = _MODEL_CONFIG
|
|
813
|
+
|
|
814
|
+
site_name: str
|
|
815
|
+
latitude: float
|
|
816
|
+
longitude: float
|
|
817
|
+
distance_miles: float
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
class NearbyProviderSite(BaseModel):
|
|
821
|
+
model_config = _MODEL_CONFIG
|
|
822
|
+
|
|
823
|
+
id: str
|
|
824
|
+
name: str
|
|
825
|
+
address: str | None = None
|
|
826
|
+
city: str | None = None
|
|
827
|
+
state: str | None = None
|
|
828
|
+
postal_code: str | None = None
|
|
829
|
+
latitude: float
|
|
830
|
+
longitude: float
|
|
831
|
+
providers: list[NearbyProviderRef]
|
|
832
|
+
matches: list[NearbyProviderSiteMatch]
|
|
833
|
+
|
|
834
|
+
|
|
835
|
+
class NearbyProviderSites(BaseModel):
|
|
836
|
+
model_config = _MODEL_CONFIG
|
|
837
|
+
|
|
838
|
+
# A value this SDK version does not know yet stays a plain string.
|
|
839
|
+
status: NearbyProviderSitesStatus | str = Field(union_mode="left_to_right")
|
|
840
|
+
truncated: bool
|
|
841
|
+
sites: list[NearbyProviderSite]
|
|
842
|
+
|
|
843
|
+
|
|
776
844
|
class AnalyzeCohortsPayload(BaseModel):
|
|
777
845
|
model_config = _MODEL_CONFIG
|
|
778
846
|
|
|
779
847
|
id: str
|
|
780
848
|
analyses: list[ProviderCohortAnalysis]
|
|
781
849
|
warnings: list[AnalysisWarning] | None = None
|
|
850
|
+
nearby_provider_sites: NearbyProviderSites | None = None
|
|
@@ -93,6 +93,14 @@ query AnalyzeCohorts($input: AnalyzeCohortsInput!) {
|
|
|
93
93
|
code
|
|
94
94
|
message
|
|
95
95
|
}
|
|
96
|
+
nearbyProviderSites {
|
|
97
|
+
status truncated
|
|
98
|
+
sites {
|
|
99
|
+
id name address city state postalCode latitude longitude
|
|
100
|
+
providers { id name providerType color }
|
|
101
|
+
matches { siteName latitude longitude distanceMiles }
|
|
102
|
+
}
|
|
103
|
+
}
|
|
96
104
|
}
|
|
97
105
|
}
|
|
98
106
|
"""
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.3.2"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|