diff --git a/.github/workflows/handle-release-pr-title-edit.yml b/.github/workflows/handle-release-pr-title-edit.yml new file mode 100644 index 00000000..19a655bf --- /dev/null +++ b/.github/workflows/handle-release-pr-title-edit.yml @@ -0,0 +1,23 @@ +name: Handle release PR title edits +on: + pull_request: + types: + - edited + - unlabeled + +jobs: + update_pr_content: + name: Update pull request content + if: | + (github.event.action == 'edited' && github.event.changes.title.from != github.event.pull_request.title) || + (github.event.action == 'unlabeled' && github.event.label.name == 'autorelease: custom version') && + github.event.pull_request.state == 'open' && + github.event.sender.login != 'stainless-bot' && + github.repository == 'Finch-API/finch-api-python' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: stainless-api/trigger-release-please@v1 + with: + repo: ${{ github.event.repository.full_name }} + stainless-api-key: ${{ secrets.STAINLESS_API_KEY }} diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 5547f83e..cda9cbdf 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.1.1" + ".": "0.1.2" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index d8ad62fa..2d2fedb9 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1 +1 @@ -configured_endpoints: 27 +configured_endpoints: 18 diff --git a/CHANGELOG.md b/CHANGELOG.md index b10f02f6..de179bec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,29 @@ # Changelog +## 0.1.2 (2023-09-19) + +Full Changelog: [v0.1.1...v0.1.2](https://github.com/Finch-API/finch-api-python/compare/v0.1.1...v0.1.2) + +### Features + +* **client:** retry on 408 Request Timeout ([#99](https://github.com/Finch-API/finch-api-python/issues/99)) ([f8d0bbf](https://github.com/Finch-API/finch-api-python/commit/f8d0bbf9f9f3bd310d4d0cad6f4f43f0a2393273)) + + +### Bug Fixes + +* **client:** properly configure model set fields ([#98](https://github.com/Finch-API/finch-api-python/issues/98)) ([ada3ad6](https://github.com/Finch-API/finch-api-python/commit/ada3ad60c40e1b26fcb0a12be0686df82f523554)) + + +### Chores + +* **api:** remove deprecated & unused ATS API ([#103](https://github.com/Finch-API/finch-api-python/issues/103)) ([96b9a92](https://github.com/Finch-API/finch-api-python/commit/96b9a923ef83207e9b3c20676cde3690a4c368d6)) +* **internal:** add helpers ([#100](https://github.com/Finch-API/finch-api-python/issues/100)) ([fec8c01](https://github.com/Finch-API/finch-api-python/commit/fec8c01ac4bee0f2a39ed42e0b4d6b2bf170ebf1)) + + +### Documentation + +* add some missing inline documentation ([#95](https://github.com/Finch-API/finch-api-python/issues/95)) ([dc178c6](https://github.com/Finch-API/finch-api-python/commit/dc178c60adc0e38291c94d2d9e5347b528e4edbe)) + ## 0.1.1 (2023-09-11) Full Changelog: [v0.1.0...v0.1.1](https://github.com/Finch-API/finch-api-python/compare/v0.1.0...v0.1.1) diff --git a/README.md b/README.md index 0ae153d8..0b907131 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,11 @@ client = Finch( access_token="my access token", ) -candidate = client.ats.candidates.retrieve( - "", +page = client.hris.directory.list_individuals( + candidate_id="", ) -print(candidate.first_name) +directory = page.individuals[0] +print(directory.first_name) ``` ## Async Usage @@ -46,10 +47,10 @@ client = AsyncFinch( async def main(): - candidate = await client.ats.candidates.retrieve( - "", + page = await client.hris.directory.list_individuals( + candidate_id="", ) - print(candidate.first_name) + print(page.individuals[0].first_name) asyncio.run(main()) @@ -74,12 +75,12 @@ import finch client = Finch() -all_jobs = [] +all_directories = [] # Automatically fetches more pages as needed. -for job in client.ats.jobs.list(): - # Do something with job here - all_jobs.append(job) -print(all_jobs) +for directory in client.hris.directory.list_individuals(): + # Do something with directory here + all_directories.append(directory) +print(all_directories) ``` Or, asynchronously: @@ -92,11 +93,11 @@ client = AsyncFinch() async def main() -> None: - all_jobs = [] + all_directories = [] # Iterate through items across all pages, issuing requests as needed. - async for job in client.ats.jobs.list(): - all_jobs.append(job) - print(all_jobs) + async for directory in client.hris.directory.list_individuals(): + all_directories.append(directory) + print(all_directories) asyncio.run(main()) @@ -105,11 +106,11 @@ asyncio.run(main()) Alternatively, you can use the `.has_next_page()`, `.next_page_info()`, or `.get_next_page()` methods for more granular control working with pages: ```python -first_page = await client.ats.jobs.list() +first_page = await client.hris.directory.list_individuals() if first_page.has_next_page(): print(f"will fetch next page using these details: {first_page.next_page_info()}") next_page = await first_page.get_next_page() - print(f"number of items we just fetched: {len(next_page.jobs)}") + print(f"number of items we just fetched: {len(next_page.individuals)}") # Remove `await` for non-async usage. ``` @@ -117,13 +118,13 @@ if first_page.has_next_page(): Or just work directly with the returned data: ```python -first_page = await client.ats.jobs.list() +first_page = await client.hris.directory.list_individuals() print( f"the current start offset for this page: {first_page.paging.offset}" ) # => "the current start offset for this page: 1" -for job in first_page.jobs: - print(job.id) +for directory in first_page.individuals: + print(directory.id) # Remove `await` for non-async usage. ``` @@ -210,8 +211,8 @@ Error codes are as followed: ### Retries Certain errors will be automatically retried 2 times by default, with a short exponential backoff. -Connection errors (for example, due to a network connectivity problem), 409 Conflict, 429 Rate Limit, -and >=500 Internal errors will all be retried by default. +Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict, +429 Rate Limit, and >=500 Internal errors will all be retried by default. You can use the `max_retries` option to configure or disable this: @@ -271,7 +272,21 @@ client = Finch( ) ``` -## Advanced: Configuring custom URLs, proxies, and transports +## Advanced + +### How to tell whether `None` means `null` or missing + +In an API response, a field may be explicitly null, or missing entirely; in either case, its value is `None` in this library. You can differentiate the two cases with `.model_fields_set`: + +```py +if response.my_field is None: + if 'my_field' not in response.model_fields_set: + print('Got json like {}, without a "my_field" key present at all.') + else: + print('Got json like {"my_field": null}.') +``` + +### Configuring custom URLs, proxies, and transports You can configure the following keyword arguments when instantiating the client: @@ -289,7 +304,7 @@ client = Finch( See the httpx documentation for information about the [`proxies`](https://www.python-httpx.org/advanced/#http-proxying) and [`transport`](https://www.python-httpx.org/advanced/#custom-transports) keyword arguments. -## Advanced: Managing HTTP resources +### Managing HTTP resources By default we will close the underlying HTTP connections whenever the client is [garbage collected](https://docs.python.org/3/reference/datamodel.html#object.__del__) is called but you can also manually close the client using the `.close()` method if desired, or with a context manager that closes when exiting. diff --git a/api.md b/api.md index 9c37bfe7..24fa1691 100644 --- a/api.md +++ b/api.md @@ -133,72 +133,6 @@ Methods: - client.hris.benefits.individuals.retrieve_many_benefits(benefit_id, \*\*params) -> SyncSinglePage[IndividualBenefit] - client.hris.benefits.individuals.unenroll_many(benefit_id, \*\*params) -> SyncSinglePage[UnenrolledIndividual] -# ATS - -## Candidates - -Types: - -```python -from finch.types.ats import Candidate -``` - -Methods: - -- client.ats.candidates.retrieve(candidate_id) -> Candidate -- client.ats.candidates.list(\*\*params) -> SyncCandidatesPage[Candidate] - -## Applications - -Types: - -```python -from finch.types.ats import Application -``` - -Methods: - -- client.ats.applications.retrieve(application_id) -> Application -- client.ats.applications.list(\*\*params) -> SyncApplicationsPage[Application] - -## Stages - -Types: - -```python -from finch.types.ats import Stage -``` - -Methods: - -- client.ats.stages.list() -> SyncSinglePage[Stage] - -## Jobs - -Types: - -```python -from finch.types.ats import Job -``` - -Methods: - -- client.ats.jobs.retrieve(job_id) -> Job -- client.ats.jobs.list(\*\*params) -> SyncJobsPage[Job] - -## Offers - -Types: - -```python -from finch.types.ats import Offer -``` - -Methods: - -- client.ats.offers.retrieve(offer_id) -> Offer -- client.ats.offers.list(\*\*params) -> SyncOffersPage[Offer] - # Providers Types: diff --git a/pyproject.toml b/pyproject.toml index 75bc97e5..01887083 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "finch-api" -version = "0.1.1" +version = "0.1.2" description = "Client library for the Finch API" readme = "README.md" authors = ["Finch "] diff --git a/release-please-config.json b/release-please-config.json index 84f82eb9..085fc4bd 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -8,6 +8,7 @@ "bump-minor-pre-major": true, "bump-patch-for-minor-pre-major": true, "pull-request-header": "Automated Release PR", + "pull-request-title-pattern": "release: ${version}", "changelog-sections": [ { "type": "feat", diff --git a/src/finch/__init__.py b/src/finch/__init__.py index 1d5b4bf5..f5214f9a 100644 --- a/src/finch/__init__.py +++ b/src/finch/__init__.py @@ -12,7 +12,6 @@ AsyncFinch, AsyncClient, AsyncStream, - ProxiesTypes, RequestOptions, ) from ._version import __title__, __version__ diff --git a/src/finch/_base_client.py b/src/finch/_base_client.py index 58309b6b..c2eca058 100644 --- a/src/finch/_base_client.py +++ b/src/finch/_base_client.py @@ -132,6 +132,17 @@ def __init__( class BasePage(GenericModel, Generic[ModelT]): + """ + Defines the core interface for pagination. + + Type Args: + ModelT: The pydantic model that represents an item in the response. + + Methods: + has_next_page(): Check if there is another page available + next_page_info(): Get the necesary information to make a request for the next page + """ + _options: FinalRequestOptions = PrivateAttr() _model: Type[ModelT] = PrivateAttr() @@ -293,6 +304,8 @@ class BaseClient: max_retries: int timeout: Union[float, Timeout, None] _limits: httpx.Limits + _proxies: ProxiesTypes | None + _transport: Transport | None _strict_response_validation: bool _idempotency_header: str | None @@ -304,6 +317,8 @@ def __init__( max_retries: int = DEFAULT_MAX_RETRIES, timeout: float | Timeout | None = DEFAULT_TIMEOUT, limits: httpx.Limits, + transport: Transport | None, + proxies: ProxiesTypes | None, custom_headers: Mapping[str, str] | None = None, custom_query: Mapping[str, object] | None = None, ) -> None: @@ -311,6 +326,8 @@ def __init__( self.max_retries = max_retries self.timeout = timeout self._limits = limits + self._proxies = proxies + self._transport = transport self._custom_headers = custom_headers or {} self._custom_query = custom_query or {} self._strict_response_validation = _strict_response_validation @@ -579,6 +596,11 @@ def user_agent(self) -> str: def base_url(self) -> URL: return self._client.base_url + @base_url.setter + def base_url(self, url: URL | str) -> None: + # mypy doesn't use the type from the setter + self._client.base_url = url # type: ignore[assignment] + @lru_cache(maxsize=None) def platform_headers(self) -> Dict[str, str]: return { @@ -633,6 +655,10 @@ def _should_retry(self, response: httpx.Response) -> bool: if should_retry_header == "false": return False + # Retry on request timeouts. + if response.status_code == 408: + return True + # Retry on lock timeouts. if response.status_code == 409: return True @@ -674,6 +700,8 @@ def __init__( version=version, limits=limits, timeout=timeout, + proxies=proxies, + transport=transport, max_retries=max_retries, custom_query=custom_query, custom_headers=custom_headers, @@ -1030,6 +1058,8 @@ def __init__( version=version, limits=limits, timeout=timeout, + proxies=proxies, + transport=transport, max_retries=max_retries, custom_query=custom_query, custom_headers=custom_headers, diff --git a/src/finch/_client.py b/src/finch/_client.py index 2399240c..95dcba16 100644 --- a/src/finch/_client.py +++ b/src/finch/_client.py @@ -46,7 +46,6 @@ class Finch(SyncAPIClient): hris: resources.HRIS - ats: resources.ATS providers: resources.Providers account: resources.Account webhooks: resources.Webhooks @@ -120,7 +119,6 @@ def __init__( ) self.hris = resources.HRIS(self) - self.ats = resources.ATS(self) self.providers = resources.Providers(self) self.account = resources.Account(self) self.webhooks = resources.Webhooks(self) @@ -279,7 +277,6 @@ def get_auth_url( class AsyncFinch(AsyncAPIClient): hris: resources.AsyncHRIS - ats: resources.AsyncATS providers: resources.AsyncProviders account: resources.AsyncAccount webhooks: resources.AsyncWebhooks @@ -353,7 +350,6 @@ def __init__( ) self.hris = resources.AsyncHRIS(self) - self.ats = resources.AsyncATS(self) self.providers = resources.AsyncProviders(self) self.account = resources.AsyncAccount(self) self.webhooks = resources.AsyncWebhooks(self) diff --git a/src/finch/_models.py b/src/finch/_models.py index 296d36c0..7bbdca3b 100644 --- a/src/finch/_models.py +++ b/src/finch/_models.py @@ -49,6 +49,11 @@ class BaseModel(pydantic.BaseModel): model_config: ClassVar[ConfigDict] = ConfigDict(extra="allow") else: + @property + def model_fields_set(self) -> set[str]: + # a forwards-compat shim for pydantic v2 + return self.__fields_set__ # type: ignore + class Config(pydantic.BaseConfig): # pyright: ignore[reportDeprecated] extra: Any = Extra.allow # type: ignore @@ -74,6 +79,9 @@ def construct( else config.get("populate_by_name") ) + if _fields_set is None: + _fields_set = set() + model_fields = get_model_fields(cls) for name, field in model_fields.items(): key = field.alias @@ -82,6 +90,7 @@ def construct( if key in values: fields_values[name] = _construct_field(value=values[key], field=field, key=key) + _fields_set.add(name) else: fields_values[name] = field_get_default(field) @@ -94,8 +103,6 @@ def construct( fields_values[key] = value object.__setattr__(m, "__dict__", fields_values) - if _fields_set is None: - _fields_set = set(fields_values.keys()) if PYDANTIC_V2: # these properties are copied from Pydantic's `model_construct()` method diff --git a/src/finch/_utils/__init__.py b/src/finch/_utils/__init__.py index b45dc1b1..679193bd 100644 --- a/src/finch/_utils/__init__.py +++ b/src/finch/_utils/__init__.py @@ -1,3 +1,4 @@ +from ._proxy import LazyProxy as LazyProxy from ._utils import flatten as flatten from ._utils import is_dict as is_dict from ._utils import is_list as is_list diff --git a/src/finch/_utils/_proxy.py b/src/finch/_utils/_proxy.py new file mode 100644 index 00000000..fd85ebd5 --- /dev/null +++ b/src/finch/_utils/_proxy.py @@ -0,0 +1,57 @@ +from __future__ import annotations + +from abc import ABC, abstractmethod +from typing import Generic, TypeVar, Iterable, cast +from typing_extensions import ClassVar + +T = TypeVar("T") + + +class LazyProxy(Generic[T], ABC): + """Implements data methods to pretend that an instance is another instance. + + This includes forwarding attribute access and othe methods. + """ + + should_cache: ClassVar[bool] = False + + def __init__(self) -> None: + self.__proxied: T | None = None + + def __getattr__(self, attr: str) -> object: + return getattr(self.__get_proxied__(), attr) + + def __repr__(self) -> str: + return repr(self.__get_proxied__()) + + def __str__(self) -> str: + return str(self.__get_proxied__()) + + def __dir__(self) -> Iterable[str]: + return self.__get_proxied__().__dir__() + + @property # type: ignore + def __class__(self) -> type: + return self.__get_proxied__().__class__ + + def __get_proxied__(self) -> T: + if not self.should_cache: + return self.__load__() + + proxied = self.__proxied + if proxied is not None: + return proxied + + self.__proxied = proxied = self.__load__() + return proxied + + def __set_proxied__(self, value: T) -> None: + self.__proxied = value + + def __as_proxied__(self) -> T: + """Helper method that returns the current proxy, typed as the loaded object""" + return cast(T, self) + + @abstractmethod + def __load__(self) -> T: + ... diff --git a/src/finch/_utils/_transform.py b/src/finch/_utils/_transform.py index 9bb71090..c007d8b0 100644 --- a/src/finch/_utils/_transform.py +++ b/src/finch/_utils/_transform.py @@ -108,6 +108,10 @@ def _get_annoted_type(type_: type) -> type | None: def _maybe_transform_key(key: str, type_: type) -> str: + """Transform the given `data` based on the annotations provided in `type_`. + + Note: this function only looks at `Annotated` types that contain `PropertInfo` metadata. + """ annotated_type = _get_annoted_type(type_) if annotated_type is None: # no `Annotated` definition for this type, no transformation needed diff --git a/src/finch/_utils/_utils.py b/src/finch/_utils/_utils.py index dde4b457..603f7c10 100644 --- a/src/finch/_utils/_utils.py +++ b/src/finch/_utils/_utils.py @@ -27,6 +27,12 @@ def extract_files( *, paths: Sequence[Sequence[str]], ) -> list[tuple[str, FileTypes]]: + """Recursively extract files from the given dictionary based on specified paths. + + A path may look like this ['foo', 'files', '', 'data']. + + Note: this mutates the given dictionary. + """ files: list[tuple[str, FileTypes]] = [] for path in paths: files.extend(_extract_items(query, path, index=0, flattened_key=None)) diff --git a/src/finch/_version.py b/src/finch/_version.py index dee1fc53..a0e01b27 100644 --- a/src/finch/_version.py +++ b/src/finch/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. __title__ = "finch" -__version__ = "0.1.1" # x-release-please-version +__version__ = "0.1.2" # x-release-please-version diff --git a/src/finch/pagination.py b/src/finch/pagination.py index e1a57f18..688366a1 100644 --- a/src/finch/pagination.py +++ b/src/finch/pagination.py @@ -17,14 +17,6 @@ "AsyncResponsesPage", "SyncIndividualsPage", "AsyncIndividualsPage", - "SyncCandidatesPage", - "AsyncCandidatesPage", - "SyncApplicationsPage", - "AsyncApplicationsPage", - "SyncJobsPage", - "AsyncJobsPage", - "SyncOffersPage", - "AsyncOffersPage", ] _BaseModelT = TypeVar("_BaseModelT", bound=BaseModel) @@ -154,219 +146,3 @@ def next_page_info(self) -> Optional[PageInfo]: return PageInfo(params={"offset": current_count}) return None - - -CandidatesPagePaging = Paging -"""This is deprecated, Paging should be used instead""" - - -class SyncCandidatesPage(BaseSyncPage[ModelT], BasePage[ModelT], Generic[ModelT]): - candidates: List[ModelT] - paging: Paging - - def _get_page_items(self) -> List[ModelT]: - return self.candidates - - def next_page_info(self) -> Optional[PageInfo]: - offset = self.paging.offset - if offset is None: - return None - - length = len(self.candidates) - current_count = offset + length - - total_count = self.paging.count - if total_count is None: - return None - - if current_count < total_count: - return PageInfo(params={"offset": current_count}) - - return None - - -class AsyncCandidatesPage(BaseAsyncPage[ModelT], BasePage[ModelT], Generic[ModelT]): - candidates: List[ModelT] - paging: Paging - - def _get_page_items(self) -> List[ModelT]: - return self.candidates - - def next_page_info(self) -> Optional[PageInfo]: - offset = self.paging.offset - if offset is None: - return None - - length = len(self.candidates) - current_count = offset + length - - total_count = self.paging.count - if total_count is None: - return None - - if current_count < total_count: - return PageInfo(params={"offset": current_count}) - - return None - - -ApplicationsPagePaging = Paging -"""This is deprecated, Paging should be used instead""" - - -class SyncApplicationsPage(BaseSyncPage[ModelT], BasePage[ModelT], Generic[ModelT]): - applications: List[ModelT] - paging: Paging - - def _get_page_items(self) -> List[ModelT]: - return self.applications - - def next_page_info(self) -> Optional[PageInfo]: - offset = self.paging.offset - if offset is None: - return None - - length = len(self.applications) - current_count = offset + length - - total_count = self.paging.count - if total_count is None: - return None - - if current_count < total_count: - return PageInfo(params={"offset": current_count}) - - return None - - -class AsyncApplicationsPage(BaseAsyncPage[ModelT], BasePage[ModelT], Generic[ModelT]): - applications: List[ModelT] - paging: Paging - - def _get_page_items(self) -> List[ModelT]: - return self.applications - - def next_page_info(self) -> Optional[PageInfo]: - offset = self.paging.offset - if offset is None: - return None - - length = len(self.applications) - current_count = offset + length - - total_count = self.paging.count - if total_count is None: - return None - - if current_count < total_count: - return PageInfo(params={"offset": current_count}) - - return None - - -JobsPagePaging = Paging -"""This is deprecated, Paging should be used instead""" - - -class SyncJobsPage(BaseSyncPage[ModelT], BasePage[ModelT], Generic[ModelT]): - jobs: List[ModelT] - paging: Paging - - def _get_page_items(self) -> List[ModelT]: - return self.jobs - - def next_page_info(self) -> Optional[PageInfo]: - offset = self.paging.offset - if offset is None: - return None - - length = len(self.jobs) - current_count = offset + length - - total_count = self.paging.count - if total_count is None: - return None - - if current_count < total_count: - return PageInfo(params={"offset": current_count}) - - return None - - -class AsyncJobsPage(BaseAsyncPage[ModelT], BasePage[ModelT], Generic[ModelT]): - jobs: List[ModelT] - paging: Paging - - def _get_page_items(self) -> List[ModelT]: - return self.jobs - - def next_page_info(self) -> Optional[PageInfo]: - offset = self.paging.offset - if offset is None: - return None - - length = len(self.jobs) - current_count = offset + length - - total_count = self.paging.count - if total_count is None: - return None - - if current_count < total_count: - return PageInfo(params={"offset": current_count}) - - return None - - -OffersPagePaging = Paging -"""This is deprecated, Paging should be used instead""" - - -class SyncOffersPage(BaseSyncPage[ModelT], BasePage[ModelT], Generic[ModelT]): - offers: List[ModelT] - paging: Paging - - def _get_page_items(self) -> List[ModelT]: - return self.offers - - def next_page_info(self) -> Optional[PageInfo]: - offset = self.paging.offset - if offset is None: - return None - - length = len(self.offers) - current_count = offset + length - - total_count = self.paging.count - if total_count is None: - return None - - if current_count < total_count: - return PageInfo(params={"offset": current_count}) - - return None - - -class AsyncOffersPage(BaseAsyncPage[ModelT], BasePage[ModelT], Generic[ModelT]): - offers: List[ModelT] - paging: Paging - - def _get_page_items(self) -> List[ModelT]: - return self.offers - - def next_page_info(self) -> Optional[PageInfo]: - offset = self.paging.offset - if offset is None: - return None - - length = len(self.offers) - current_count = offset + length - - total_count = self.paging.count - if total_count is None: - return None - - if current_count < total_count: - return PageInfo(params={"offset": current_count}) - - return None diff --git a/src/finch/resources/__init__.py b/src/finch/resources/__init__.py index 2008f217..1a47fea5 100644 --- a/src/finch/resources/__init__.py +++ b/src/finch/resources/__init__.py @@ -1,20 +1,8 @@ # File generated from our OpenAPI spec by Stainless. -from .ats import ATS, AsyncATS from .hris import HRIS, AsyncHRIS from .account import Account, AsyncAccount from .webhooks import Webhooks, AsyncWebhooks from .providers import Providers, AsyncProviders -__all__ = [ - "HRIS", - "AsyncHRIS", - "ATS", - "AsyncATS", - "Providers", - "AsyncProviders", - "Account", - "AsyncAccount", - "Webhooks", - "AsyncWebhooks", -] +__all__ = ["HRIS", "AsyncHRIS", "Providers", "AsyncProviders", "Account", "AsyncAccount", "Webhooks", "AsyncWebhooks"] diff --git a/src/finch/resources/ats/__init__.py b/src/finch/resources/ats/__init__.py deleted file mode 100644 index 4d718632..00000000 --- a/src/finch/resources/ats/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from .ats import ATS, AsyncATS -from .jobs import Jobs, AsyncJobs -from .offers import Offers, AsyncOffers -from .stages import Stages, AsyncStages -from .candidates import Candidates, AsyncCandidates -from .applications import Applications, AsyncApplications - -__all__ = [ - "Candidates", - "AsyncCandidates", - "Applications", - "AsyncApplications", - "Stages", - "AsyncStages", - "Jobs", - "AsyncJobs", - "Offers", - "AsyncOffers", - "ATS", - "AsyncATS", -] diff --git a/src/finch/resources/ats/applications.py b/src/finch/resources/ats/applications.py deleted file mode 100644 index 617c2e70..00000000 --- a/src/finch/resources/ats/applications.py +++ /dev/null @@ -1,172 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven -from ..._utils import maybe_transform -from ..._resource import SyncAPIResource, AsyncAPIResource -from ...types.ats import Application, application_list_params -from ...pagination import SyncApplicationsPage, AsyncApplicationsPage -from ..._base_client import AsyncPaginator, make_request_options - -__all__ = ["Applications", "AsyncApplications"] - - -class Applications(SyncAPIResource): - def retrieve( - self, - application_id: str, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> Application: - """ - Gets an application from an organization. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get( - f"/ats/applications/{application_id}", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=Application, - ) - - def list( - self, - *, - limit: int | NotGiven = NOT_GIVEN, - offset: int | NotGiven = NOT_GIVEN, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> SyncApplicationsPage[Application]: - """ - Gets all of an organization's applications. - - Args: - limit: Number of applications to return (defaults to all) - - offset: Index to start from (defaults to 0) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get_api_list( - "/ats/applications", - page=SyncApplicationsPage[Application], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "limit": limit, - "offset": offset, - }, - application_list_params.ApplicationListParams, - ), - ), - model=Application, - ) - - -class AsyncApplications(AsyncAPIResource): - async def retrieve( - self, - application_id: str, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> Application: - """ - Gets an application from an organization. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return await self._get( - f"/ats/applications/{application_id}", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=Application, - ) - - def list( - self, - *, - limit: int | NotGiven = NOT_GIVEN, - offset: int | NotGiven = NOT_GIVEN, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> AsyncPaginator[Application, AsyncApplicationsPage[Application]]: - """ - Gets all of an organization's applications. - - Args: - limit: Number of applications to return (defaults to all) - - offset: Index to start from (defaults to 0) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get_api_list( - "/ats/applications", - page=AsyncApplicationsPage[Application], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "limit": limit, - "offset": offset, - }, - application_list_params.ApplicationListParams, - ), - ), - model=Application, - ) diff --git a/src/finch/resources/ats/ats.py b/src/finch/resources/ats/ats.py deleted file mode 100644 index 843f7e20..00000000 --- a/src/finch/resources/ats/ats.py +++ /dev/null @@ -1,49 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -from typing import TYPE_CHECKING - -from .jobs import Jobs, AsyncJobs -from .offers import Offers, AsyncOffers -from .stages import Stages, AsyncStages -from .candidates import Candidates, AsyncCandidates -from ..._resource import SyncAPIResource, AsyncAPIResource -from .applications import Applications, AsyncApplications - -if TYPE_CHECKING: - from ..._client import Finch, AsyncFinch - -__all__ = ["ATS", "AsyncATS"] - - -class ATS(SyncAPIResource): - candidates: Candidates - applications: Applications - stages: Stages - jobs: Jobs - offers: Offers - - def __init__(self, client: Finch) -> None: - super().__init__(client) - self.candidates = Candidates(client) - self.applications = Applications(client) - self.stages = Stages(client) - self.jobs = Jobs(client) - self.offers = Offers(client) - - -class AsyncATS(AsyncAPIResource): - candidates: AsyncCandidates - applications: AsyncApplications - stages: AsyncStages - jobs: AsyncJobs - offers: AsyncOffers - - def __init__(self, client: AsyncFinch) -> None: - super().__init__(client) - self.candidates = AsyncCandidates(client) - self.applications = AsyncApplications(client) - self.stages = AsyncStages(client) - self.jobs = AsyncJobs(client) - self.offers = AsyncOffers(client) diff --git a/src/finch/resources/ats/candidates.py b/src/finch/resources/ats/candidates.py deleted file mode 100644 index 1bb04a89..00000000 --- a/src/finch/resources/ats/candidates.py +++ /dev/null @@ -1,180 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven -from ..._utils import maybe_transform -from ..._resource import SyncAPIResource, AsyncAPIResource -from ...types.ats import Candidate, candidate_list_params -from ...pagination import SyncCandidatesPage, AsyncCandidatesPage -from ..._base_client import AsyncPaginator, make_request_options - -__all__ = ["Candidates", "AsyncCandidates"] - - -class Candidates(SyncAPIResource): - def retrieve( - self, - candidate_id: str, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> Candidate: - """Gets a candidate from an organization. - - A candidate represents an individual - associated with one or more applications. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get( - f"/ats/candidates/{candidate_id}", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=Candidate, - ) - - def list( - self, - *, - limit: int | NotGiven = NOT_GIVEN, - offset: int | NotGiven = NOT_GIVEN, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> SyncCandidatesPage[Candidate]: - """Gets all of an organization's candidates. - - A candidate represents an individual - associated with one or more applications. - - Args: - limit: Number of candidates to return (defaults to all) - - offset: Index to start from (defaults to 0) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get_api_list( - "/ats/candidates", - page=SyncCandidatesPage[Candidate], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "limit": limit, - "offset": offset, - }, - candidate_list_params.CandidateListParams, - ), - ), - model=Candidate, - ) - - -class AsyncCandidates(AsyncAPIResource): - async def retrieve( - self, - candidate_id: str, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> Candidate: - """Gets a candidate from an organization. - - A candidate represents an individual - associated with one or more applications. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return await self._get( - f"/ats/candidates/{candidate_id}", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=Candidate, - ) - - def list( - self, - *, - limit: int | NotGiven = NOT_GIVEN, - offset: int | NotGiven = NOT_GIVEN, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> AsyncPaginator[Candidate, AsyncCandidatesPage[Candidate]]: - """Gets all of an organization's candidates. - - A candidate represents an individual - associated with one or more applications. - - Args: - limit: Number of candidates to return (defaults to all) - - offset: Index to start from (defaults to 0) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get_api_list( - "/ats/candidates", - page=AsyncCandidatesPage[Candidate], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "limit": limit, - "offset": offset, - }, - candidate_list_params.CandidateListParams, - ), - ), - model=Candidate, - ) diff --git a/src/finch/resources/ats/jobs.py b/src/finch/resources/ats/jobs.py deleted file mode 100644 index d2c43f21..00000000 --- a/src/finch/resources/ats/jobs.py +++ /dev/null @@ -1,172 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven -from ..._utils import maybe_transform -from ..._resource import SyncAPIResource, AsyncAPIResource -from ...types.ats import Job, job_list_params -from ...pagination import SyncJobsPage, AsyncJobsPage -from ..._base_client import AsyncPaginator, make_request_options - -__all__ = ["Jobs", "AsyncJobs"] - - -class Jobs(SyncAPIResource): - def retrieve( - self, - job_id: str, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> Job: - """ - Gets a job from an organization. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get( - f"/ats/jobs/{job_id}", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=Job, - ) - - def list( - self, - *, - limit: int | NotGiven = NOT_GIVEN, - offset: int | NotGiven = NOT_GIVEN, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> SyncJobsPage[Job]: - """ - Gets all of an organization's jobs. - - Args: - limit: Number of jobs to return (defaults to all) - - offset: Index to start from (defaults to 0) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get_api_list( - "/ats/jobs", - page=SyncJobsPage[Job], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "limit": limit, - "offset": offset, - }, - job_list_params.JobListParams, - ), - ), - model=Job, - ) - - -class AsyncJobs(AsyncAPIResource): - async def retrieve( - self, - job_id: str, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> Job: - """ - Gets a job from an organization. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return await self._get( - f"/ats/jobs/{job_id}", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=Job, - ) - - def list( - self, - *, - limit: int | NotGiven = NOT_GIVEN, - offset: int | NotGiven = NOT_GIVEN, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> AsyncPaginator[Job, AsyncJobsPage[Job]]: - """ - Gets all of an organization's jobs. - - Args: - limit: Number of jobs to return (defaults to all) - - offset: Index to start from (defaults to 0) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get_api_list( - "/ats/jobs", - page=AsyncJobsPage[Job], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "limit": limit, - "offset": offset, - }, - job_list_params.JobListParams, - ), - ), - model=Job, - ) diff --git a/src/finch/resources/ats/offers.py b/src/finch/resources/ats/offers.py deleted file mode 100644 index 55a8a8ab..00000000 --- a/src/finch/resources/ats/offers.py +++ /dev/null @@ -1,172 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven -from ..._utils import maybe_transform -from ..._resource import SyncAPIResource, AsyncAPIResource -from ...types.ats import Offer, offer_list_params -from ...pagination import SyncOffersPage, AsyncOffersPage -from ..._base_client import AsyncPaginator, make_request_options - -__all__ = ["Offers", "AsyncOffers"] - - -class Offers(SyncAPIResource): - def retrieve( - self, - offer_id: str, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> Offer: - """ - Get a single offer from an organization. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get( - f"/ats/offers/{offer_id}", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=Offer, - ) - - def list( - self, - *, - limit: int | NotGiven = NOT_GIVEN, - offset: int | NotGiven = NOT_GIVEN, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> SyncOffersPage[Offer]: - """ - Get all offers put out by an organization. - - Args: - limit: Number of offers to return (defaults to all) - - offset: Index to start from (defaults to 0) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get_api_list( - "/ats/offers", - page=SyncOffersPage[Offer], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "limit": limit, - "offset": offset, - }, - offer_list_params.OfferListParams, - ), - ), - model=Offer, - ) - - -class AsyncOffers(AsyncAPIResource): - async def retrieve( - self, - offer_id: str, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> Offer: - """ - Get a single offer from an organization. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return await self._get( - f"/ats/offers/{offer_id}", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=Offer, - ) - - def list( - self, - *, - limit: int | NotGiven = NOT_GIVEN, - offset: int | NotGiven = NOT_GIVEN, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> AsyncPaginator[Offer, AsyncOffersPage[Offer]]: - """ - Get all offers put out by an organization. - - Args: - limit: Number of offers to return (defaults to all) - - offset: Index to start from (defaults to 0) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get_api_list( - "/ats/offers", - page=AsyncOffersPage[Offer], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "limit": limit, - "offset": offset, - }, - offer_list_params.OfferListParams, - ), - ), - model=Offer, - ) diff --git a/src/finch/resources/ats/stages.py b/src/finch/resources/ats/stages.py deleted file mode 100644 index 0974e2de..00000000 --- a/src/finch/resources/ats/stages.py +++ /dev/null @@ -1,67 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven -from ..._resource import SyncAPIResource, AsyncAPIResource -from ...types.ats import Stage -from ...pagination import SyncSinglePage, AsyncSinglePage -from ..._base_client import AsyncPaginator, make_request_options - -__all__ = ["Stages", "AsyncStages"] - - -class Stages(SyncAPIResource): - def list( - self, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> SyncSinglePage[Stage]: - """Get all job stages for an organization. - - Depending on the system, some jobs may - have stages specific to that job. Other job stages may apply broadly to all jobs - in the system. Use the `job_id` to determine whether a job applies specifically - to a job. - """ - return self._get_api_list( - "/ats/stages", - page=SyncSinglePage[Stage], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=Stage, - ) - - -class AsyncStages(AsyncAPIResource): - def list( - self, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> AsyncPaginator[Stage, AsyncSinglePage[Stage]]: - """Get all job stages for an organization. - - Depending on the system, some jobs may - have stages specific to that job. Other job stages may apply broadly to all jobs - in the system. Use the `job_id` to determine whether a job applies specifically - to a job. - """ - return self._get_api_list( - "/ats/stages", - page=AsyncSinglePage[Stage], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=Stage, - ) diff --git a/src/finch/types/ats/__init__.py b/src/finch/types/ats/__init__.py deleted file mode 100644 index 8ead8f42..00000000 --- a/src/finch/types/ats/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -from .job import Job as Job -from .offer import Offer as Offer -from .stage import Stage as Stage -from .candidate import Candidate as Candidate -from .application import Application as Application -from .job_list_params import JobListParams as JobListParams -from .offer_list_params import OfferListParams as OfferListParams -from .candidate_list_params import CandidateListParams as CandidateListParams -from .application_list_params import ApplicationListParams as ApplicationListParams diff --git a/src/finch/types/ats/application.py b/src/finch/types/ats/application.py deleted file mode 100644 index 4c4780ba..00000000 --- a/src/finch/types/ats/application.py +++ /dev/null @@ -1,29 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from typing import Optional -from datetime import datetime - -from .stage import Stage -from ..._models import BaseModel - -__all__ = ["Application", "RejectedReason"] - - -class RejectedReason(BaseModel): - text: Optional[str] = None - - -class Application(BaseModel): - id: str - - candidate_id: str - - job_id: str - - offer_id: Optional[str] - - rejected_at: Optional[datetime] - - rejected_reason: Optional[RejectedReason] - - stage: Optional[Stage] diff --git a/src/finch/types/ats/application_list_params.py b/src/finch/types/ats/application_list_params.py deleted file mode 100644 index c6581adf..00000000 --- a/src/finch/types/ats/application_list_params.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -from typing_extensions import TypedDict - -__all__ = ["ApplicationListParams"] - - -class ApplicationListParams(TypedDict, total=False): - limit: int - """Number of applications to return (defaults to all)""" - - offset: int - """Index to start from (defaults to 0)""" diff --git a/src/finch/types/ats/candidate.py b/src/finch/types/ats/candidate.py deleted file mode 100644 index fd5ab8ce..00000000 --- a/src/finch/types/ats/candidate.py +++ /dev/null @@ -1,41 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from typing import List, Optional -from datetime import datetime - -from ..._models import BaseModel - -__all__ = ["Candidate", "Email", "PhoneNumber"] - - -class Email(BaseModel): - data: Optional[str] = None - - type: Optional[str] = None - - -class PhoneNumber(BaseModel): - data: Optional[str] = None - - type: Optional[str] = None - - -class Candidate(BaseModel): - id: str - - application_ids: List[str] - """Array of Finch uuids corresponding to `application`s for this individual""" - - created_at: datetime - - emails: List[Email] - - first_name: Optional[str] - - full_name: Optional[str] - - last_activity_at: datetime - - last_name: Optional[str] - - phone_numbers: List[PhoneNumber] diff --git a/src/finch/types/ats/candidate_list_params.py b/src/finch/types/ats/candidate_list_params.py deleted file mode 100644 index c7cac955..00000000 --- a/src/finch/types/ats/candidate_list_params.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -from typing_extensions import TypedDict - -__all__ = ["CandidateListParams"] - - -class CandidateListParams(TypedDict, total=False): - limit: int - """Number of candidates to return (defaults to all)""" - - offset: int - """Index to start from (defaults to 0)""" diff --git a/src/finch/types/ats/job.py b/src/finch/types/ats/job.py deleted file mode 100644 index 505951aa..00000000 --- a/src/finch/types/ats/job.py +++ /dev/null @@ -1,43 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from typing import List, Optional -from datetime import datetime -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = ["Job", "Department", "HiringTeam", "HiringTeamHiringManager", "HiringTeamRecruiter"] - - -class Department(BaseModel): - name: Optional[str] = None - - -class HiringTeamHiringManager(BaseModel): - name: Optional[str] = None - - -class HiringTeamRecruiter(BaseModel): - name: Optional[str] = None - - -class HiringTeam(BaseModel): - hiring_managers: Optional[List[HiringTeamHiringManager]] = None - - recruiters: Optional[List[HiringTeamRecruiter]] = None - - -class Job(BaseModel): - id: str - - closed_at: Optional[datetime] - - created_at: Optional[datetime] - - department: Department - - hiring_team: HiringTeam - - name: Optional[str] - - status: Optional[Literal["open", "closed", "on_hold", "draft", "archived"]] diff --git a/src/finch/types/ats/job_list_params.py b/src/finch/types/ats/job_list_params.py deleted file mode 100644 index d0a3c034..00000000 --- a/src/finch/types/ats/job_list_params.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -from typing_extensions import TypedDict - -__all__ = ["JobListParams"] - - -class JobListParams(TypedDict, total=False): - limit: int - """Number of jobs to return (defaults to all)""" - - offset: int - """Index to start from (defaults to 0)""" diff --git a/src/finch/types/ats/offer.py b/src/finch/types/ats/offer.py deleted file mode 100644 index f1cef5ec..00000000 --- a/src/finch/types/ats/offer.py +++ /dev/null @@ -1,26 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from datetime import datetime -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = ["Offer"] - - -class Offer(BaseModel): - id: str - - application_id: str - - candidate_id: str - - created_at: datetime - - job_id: str - - status: Literal[ - "signed", "rejected", "draft", "approval-sent", "approved", "sent", "sent-manually", "opened", "archived" - ] - - updated_at: datetime diff --git a/src/finch/types/ats/offer_list_params.py b/src/finch/types/ats/offer_list_params.py deleted file mode 100644 index 3df4dd5f..00000000 --- a/src/finch/types/ats/offer_list_params.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -from typing_extensions import TypedDict - -__all__ = ["OfferListParams"] - - -class OfferListParams(TypedDict, total=False): - limit: int - """Number of offers to return (defaults to all)""" - - offset: int - """Index to start from (defaults to 0)""" diff --git a/src/finch/types/ats/stage.py b/src/finch/types/ats/stage.py deleted file mode 100644 index 769f92fd..00000000 --- a/src/finch/types/ats/stage.py +++ /dev/null @@ -1,19 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from typing import Optional - -from ..._models import BaseModel - -__all__ = ["Stage"] - - -class Stage(BaseModel): - id: Optional[str] = None - - job_id: Optional[str] = None - """The job id that this stage applies to, if applicable. - - Not all systems enumerate stages specific to jobs. - """ - - name: Optional[str] = None diff --git a/tests/api_resources/ats/__init__.py b/tests/api_resources/ats/__init__.py deleted file mode 100644 index 1016754e..00000000 --- a/tests/api_resources/ats/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. diff --git a/tests/api_resources/ats/test_applications.py b/tests/api_resources/ats/test_applications.py deleted file mode 100644 index 623dbf24..00000000 --- a/tests/api_resources/ats/test_applications.py +++ /dev/null @@ -1,67 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -import os - -import pytest - -from finch import Finch, AsyncFinch -from tests.utils import assert_matches_type -from finch.types.ats import Application -from finch.pagination import SyncApplicationsPage, AsyncApplicationsPage - -base_url = os.environ.get("API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") - - -class TestApplications: - strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True) - loose_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) - - @parametrize - def test_method_retrieve(self, client: Finch) -> None: - application = client.ats.applications.retrieve( - "string", - ) - assert_matches_type(Application, application, path=["response"]) - - @parametrize - def test_method_list(self, client: Finch) -> None: - application = client.ats.applications.list() - assert_matches_type(SyncApplicationsPage[Application], application, path=["response"]) - - @parametrize - def test_method_list_with_all_params(self, client: Finch) -> None: - application = client.ats.applications.list( - limit=0, - offset=0, - ) - assert_matches_type(SyncApplicationsPage[Application], application, path=["response"]) - - -class TestAsyncApplications: - strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True) - loose_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) - - @parametrize - async def test_method_retrieve(self, client: AsyncFinch) -> None: - application = await client.ats.applications.retrieve( - "string", - ) - assert_matches_type(Application, application, path=["response"]) - - @parametrize - async def test_method_list(self, client: AsyncFinch) -> None: - application = await client.ats.applications.list() - assert_matches_type(AsyncApplicationsPage[Application], application, path=["response"]) - - @parametrize - async def test_method_list_with_all_params(self, client: AsyncFinch) -> None: - application = await client.ats.applications.list( - limit=0, - offset=0, - ) - assert_matches_type(AsyncApplicationsPage[Application], application, path=["response"]) diff --git a/tests/api_resources/ats/test_candidates.py b/tests/api_resources/ats/test_candidates.py deleted file mode 100644 index 9acb013d..00000000 --- a/tests/api_resources/ats/test_candidates.py +++ /dev/null @@ -1,67 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -import os - -import pytest - -from finch import Finch, AsyncFinch -from tests.utils import assert_matches_type -from finch.types.ats import Candidate -from finch.pagination import SyncCandidatesPage, AsyncCandidatesPage - -base_url = os.environ.get("API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") - - -class TestCandidates: - strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True) - loose_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) - - @parametrize - def test_method_retrieve(self, client: Finch) -> None: - candidate = client.ats.candidates.retrieve( - "string", - ) - assert_matches_type(Candidate, candidate, path=["response"]) - - @parametrize - def test_method_list(self, client: Finch) -> None: - candidate = client.ats.candidates.list() - assert_matches_type(SyncCandidatesPage[Candidate], candidate, path=["response"]) - - @parametrize - def test_method_list_with_all_params(self, client: Finch) -> None: - candidate = client.ats.candidates.list( - limit=0, - offset=0, - ) - assert_matches_type(SyncCandidatesPage[Candidate], candidate, path=["response"]) - - -class TestAsyncCandidates: - strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True) - loose_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) - - @parametrize - async def test_method_retrieve(self, client: AsyncFinch) -> None: - candidate = await client.ats.candidates.retrieve( - "string", - ) - assert_matches_type(Candidate, candidate, path=["response"]) - - @parametrize - async def test_method_list(self, client: AsyncFinch) -> None: - candidate = await client.ats.candidates.list() - assert_matches_type(AsyncCandidatesPage[Candidate], candidate, path=["response"]) - - @parametrize - async def test_method_list_with_all_params(self, client: AsyncFinch) -> None: - candidate = await client.ats.candidates.list( - limit=0, - offset=0, - ) - assert_matches_type(AsyncCandidatesPage[Candidate], candidate, path=["response"]) diff --git a/tests/api_resources/ats/test_jobs.py b/tests/api_resources/ats/test_jobs.py deleted file mode 100644 index cbe6e7b7..00000000 --- a/tests/api_resources/ats/test_jobs.py +++ /dev/null @@ -1,67 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -import os - -import pytest - -from finch import Finch, AsyncFinch -from tests.utils import assert_matches_type -from finch.types.ats import Job -from finch.pagination import SyncJobsPage, AsyncJobsPage - -base_url = os.environ.get("API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") - - -class TestJobs: - strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True) - loose_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) - - @parametrize - def test_method_retrieve(self, client: Finch) -> None: - job = client.ats.jobs.retrieve( - "string", - ) - assert_matches_type(Job, job, path=["response"]) - - @parametrize - def test_method_list(self, client: Finch) -> None: - job = client.ats.jobs.list() - assert_matches_type(SyncJobsPage[Job], job, path=["response"]) - - @parametrize - def test_method_list_with_all_params(self, client: Finch) -> None: - job = client.ats.jobs.list( - limit=0, - offset=0, - ) - assert_matches_type(SyncJobsPage[Job], job, path=["response"]) - - -class TestAsyncJobs: - strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True) - loose_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) - - @parametrize - async def test_method_retrieve(self, client: AsyncFinch) -> None: - job = await client.ats.jobs.retrieve( - "string", - ) - assert_matches_type(Job, job, path=["response"]) - - @parametrize - async def test_method_list(self, client: AsyncFinch) -> None: - job = await client.ats.jobs.list() - assert_matches_type(AsyncJobsPage[Job], job, path=["response"]) - - @parametrize - async def test_method_list_with_all_params(self, client: AsyncFinch) -> None: - job = await client.ats.jobs.list( - limit=0, - offset=0, - ) - assert_matches_type(AsyncJobsPage[Job], job, path=["response"]) diff --git a/tests/api_resources/ats/test_offers.py b/tests/api_resources/ats/test_offers.py deleted file mode 100644 index a18e4550..00000000 --- a/tests/api_resources/ats/test_offers.py +++ /dev/null @@ -1,67 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -import os - -import pytest - -from finch import Finch, AsyncFinch -from tests.utils import assert_matches_type -from finch.types.ats import Offer -from finch.pagination import SyncOffersPage, AsyncOffersPage - -base_url = os.environ.get("API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") - - -class TestOffers: - strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True) - loose_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) - - @parametrize - def test_method_retrieve(self, client: Finch) -> None: - offer = client.ats.offers.retrieve( - "string", - ) - assert_matches_type(Offer, offer, path=["response"]) - - @parametrize - def test_method_list(self, client: Finch) -> None: - offer = client.ats.offers.list() - assert_matches_type(SyncOffersPage[Offer], offer, path=["response"]) - - @parametrize - def test_method_list_with_all_params(self, client: Finch) -> None: - offer = client.ats.offers.list( - limit=0, - offset=0, - ) - assert_matches_type(SyncOffersPage[Offer], offer, path=["response"]) - - -class TestAsyncOffers: - strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True) - loose_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) - - @parametrize - async def test_method_retrieve(self, client: AsyncFinch) -> None: - offer = await client.ats.offers.retrieve( - "string", - ) - assert_matches_type(Offer, offer, path=["response"]) - - @parametrize - async def test_method_list(self, client: AsyncFinch) -> None: - offer = await client.ats.offers.list() - assert_matches_type(AsyncOffersPage[Offer], offer, path=["response"]) - - @parametrize - async def test_method_list_with_all_params(self, client: AsyncFinch) -> None: - offer = await client.ats.offers.list( - limit=0, - offset=0, - ) - assert_matches_type(AsyncOffersPage[Offer], offer, path=["response"]) diff --git a/tests/api_resources/ats/test_stages.py b/tests/api_resources/ats/test_stages.py deleted file mode 100644 index b4a89e9d..00000000 --- a/tests/api_resources/ats/test_stages.py +++ /dev/null @@ -1,37 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -import os - -import pytest - -from finch import Finch, AsyncFinch -from tests.utils import assert_matches_type -from finch.types.ats import Stage -from finch.pagination import SyncSinglePage, AsyncSinglePage - -base_url = os.environ.get("API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") - - -class TestStages: - strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True) - loose_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) - - @parametrize - def test_method_list(self, client: Finch) -> None: - stage = client.ats.stages.list() - assert_matches_type(SyncSinglePage[Stage], stage, path=["response"]) - - -class TestAsyncStages: - strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True) - loose_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) - - @parametrize - async def test_method_list(self, client: AsyncFinch) -> None: - stage = await client.ats.stages.list() - assert_matches_type(AsyncSinglePage[Stage], stage, path=["response"]) diff --git a/tests/test_models.py b/tests/test_models.py index a839f68d..e6b67abe 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -471,3 +471,17 @@ def model_id(self) -> str: assert m.model_id == "id" assert m.resource_id == "id" assert m.resource_id is m.model_id + + +def test_omitted_fields() -> None: + class Model(BaseModel): + resource_id: Optional[str] = None + + m = Model.construct() + assert "resource_id" not in m.model_fields_set + + m = Model.construct(resource_id=None) + assert "resource_id" in m.model_fields_set + + m = Model.construct(resource_id="foo") + assert "resource_id" in m.model_fields_set