diff --git a/previous-versions/files/README.md b/previous-versions/files/README.md index 8fc71f822..08971f789 100644 --- a/previous-versions/files/README.md +++ b/previous-versions/files/README.md @@ -6,15 +6,56 @@ Use Codat's Files API to upload your SMB customers' files. -replace me +## SDK Installation + +```bash +pip install codat-files +``` ## Example Usage -replace me +```python +import codatfiles +from codatfiles.models import operations, shared + +s = codatfiles.CodatFiles( + auth_header="Basic BASE_64_ENCODED(API_KEY)", +) + +req = operations.DownloadFilesRequest( + company_id='8a210b68-6988-11ed-a1eb-0242ac120002', + date_='2022-10-23T00:00:00.000Z', +) + +res = s.files.download_files(req) + +if res.data is not None: + # handle response + pass +``` -replace me +## Available Resources and Operations + + +### [files](docs/sdks/files/README.md) + +* [download_files](docs/sdks/files/README.md#download_files) - Download all files for a company +* [list_files](docs/sdks/files/README.md#list_files) - List all files uploaded by a company +* [upload_files](docs/sdks/files/README.md#upload_files) - Upload files for a company + + + + + + + + + + + + ### Library generated by [Speakeasy](https://docs.speakeasyapi.dev/docs/using-speakeasy/client-sdks) \ No newline at end of file diff --git a/previous-versions/files/RELEASES.md b/previous-versions/files/RELEASES.md new file mode 100644 index 000000000..7e7b0fef5 --- /dev/null +++ b/previous-versions/files/RELEASES.md @@ -0,0 +1,11 @@ + + +## 2023-10-17 14:12:27 +### Changes +Based on: +- OpenAPI Doc 3.0.0 https://raw.githubusercontent.com/codatio/oas/main/yaml/Codat-Files.yaml +- Speakeasy CLI 1.100.2 (2.159.2) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v0.1.0] previous-versions/files +### Releases +- [PyPI v0.1.0] https://pypi.org/project/codat-files/0.1.0 - previous-versions/files \ No newline at end of file diff --git a/previous-versions/files/USAGE.md b/previous-versions/files/USAGE.md index 84ce20ba7..962753164 100755 --- a/previous-versions/files/USAGE.md +++ b/previous-versions/files/USAGE.md @@ -6,9 +6,7 @@ import codatfiles from codatfiles.models import operations, shared s = codatfiles.CodatFiles( - security=shared.Security( - auth_header="Basic BASE_64_ENCODED(API_KEY)", - ), + auth_header="Basic BASE_64_ENCODED(API_KEY)", ) req = operations.DownloadFilesRequest( @@ -20,5 +18,6 @@ res = s.files.download_files(req) if res.data is not None: # handle response + pass ``` \ No newline at end of file diff --git a/previous-versions/files/docs/models/operations/downloadfileserrormessage.md b/previous-versions/files/docs/models/operations/downloadfileserrormessage.md new file mode 100755 index 000000000..c4948fd72 --- /dev/null +++ b/previous-versions/files/docs/models/operations/downloadfileserrormessage.md @@ -0,0 +1,16 @@ +# DownloadFilesErrorMessage + +One or more of the resources you referenced could not be found. +This might be because your company or data connection id is wrong, or was already deleted. + + +## Fields + +| Field | Type | Required | Description | +| ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `can_be_retried` | *Optional[str]* | :heavy_minus_sign: | `True` if the error occurred transiently and can be retried. | +| `correlation_id` | *Optional[str]* | :heavy_minus_sign: | Unique identifier used to propagate to all downstream services and determine the source of the error. | +| `detailed_error_code` | *Optional[int]* | :heavy_minus_sign: | Machine readable error code used to automate processes based on the code returned. | +| `error` | *Optional[str]* | :heavy_minus_sign: | A brief description of the error. | +| `service` | *Optional[str]* | :heavy_minus_sign: | Codat's service the returned the error. | +| `status_code` | *Optional[int]* | :heavy_minus_sign: | The HTTP status code returned by the error. | \ No newline at end of file diff --git a/previous-versions/files/docs/models/operations/downloadfilesrequest.md b/previous-versions/files/docs/models/operations/downloadfilesrequest.md index 6147e9072..6ac51ea2c 100755 --- a/previous-versions/files/docs/models/operations/downloadfilesrequest.md +++ b/previous-versions/files/docs/models/operations/downloadfilesrequest.md @@ -5,5 +5,5 @@ | Field | Type | Required | Description | Example | | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | -| `company_id` | *str* | :heavy_check_mark: | N/A | 8a210b68-6988-11ed-a1eb-0242ac120002 | +| `company_id` | *str* | :heavy_check_mark: | Unique identifier for a company. | 8a210b68-6988-11ed-a1eb-0242ac120002 | | `date_` | *Optional[str]* | :heavy_minus_sign: | Only download files uploaded on this date. | 2022-10-23T00:00:00.000Z | \ No newline at end of file diff --git a/previous-versions/files/docs/models/operations/downloadfilesresponse.md b/previous-versions/files/docs/models/operations/downloadfilesresponse.md index 25b0e3818..0d1018440 100755 --- a/previous-versions/files/docs/models/operations/downloadfilesresponse.md +++ b/previous-versions/files/docs/models/operations/downloadfilesresponse.md @@ -3,10 +3,11 @@ ## Fields -| Field | Type | Required | Description | -| ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -| `content_type` | *str* | :heavy_check_mark: | N/A | -| `data` | *Optional[bytes]* | :heavy_minus_sign: | Success | -| `error_message` | [Optional[shared.ErrorMessage]](../../models/shared/errormessage.md) | :heavy_minus_sign: | The request made is not valid. | -| `status_code` | *int* | :heavy_check_mark: | N/A | -| `raw_response` | [requests.Response](https://requests.readthedocs.io/en/latest/api/#requests.Response) | :heavy_minus_sign: | N/A | \ No newline at end of file +| Field | Type | Required | Description | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `content_type` | *str* | :heavy_check_mark: | HTTP response content type for this operation | +| `data` | *Optional[requests_http.Response]* | :heavy_minus_sign: | Success | +| `error_message` | [Optional[DownloadFilesErrorMessage]](../../models/operations/downloadfileserrormessage.md) | :heavy_minus_sign: | One or more of the resources you referenced could not be found.
This might be because your company or data connection id is wrong, or was already deleted. | +| `status_code` | *int* | :heavy_check_mark: | HTTP response status code for this operation | +| `raw_response` | [requests.Response](https://requests.readthedocs.io/en/latest/api/#requests.Response) | :heavy_minus_sign: | Raw HTTP response; suitable for custom response parsing | +| `schema` | [Optional[shared.Schema]](../../models/shared/schema.md) | :heavy_minus_sign: | The request made is not valid. | \ No newline at end of file diff --git a/previous-versions/files/docs/models/operations/listfileserrormessage.md b/previous-versions/files/docs/models/operations/listfileserrormessage.md new file mode 100755 index 000000000..1a8a31739 --- /dev/null +++ b/previous-versions/files/docs/models/operations/listfileserrormessage.md @@ -0,0 +1,16 @@ +# ListFilesErrorMessage + +One or more of the resources you referenced could not be found. +This might be because your company or data connection id is wrong, or was already deleted. + + +## Fields + +| Field | Type | Required | Description | +| ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `can_be_retried` | *Optional[str]* | :heavy_minus_sign: | `True` if the error occurred transiently and can be retried. | +| `correlation_id` | *Optional[str]* | :heavy_minus_sign: | Unique identifier used to propagate to all downstream services and determine the source of the error. | +| `detailed_error_code` | *Optional[int]* | :heavy_minus_sign: | Machine readable error code used to automate processes based on the code returned. | +| `error` | *Optional[str]* | :heavy_minus_sign: | A brief description of the error. | +| `service` | *Optional[str]* | :heavy_minus_sign: | Codat's service the returned the error. | +| `status_code` | *Optional[int]* | :heavy_minus_sign: | The HTTP status code returned by the error. | \ No newline at end of file diff --git a/previous-versions/files/docs/models/operations/listfilesrequest.md b/previous-versions/files/docs/models/operations/listfilesrequest.md index bb6dd7f67..23e4a10f6 100755 --- a/previous-versions/files/docs/models/operations/listfilesrequest.md +++ b/previous-versions/files/docs/models/operations/listfilesrequest.md @@ -5,4 +5,4 @@ | Field | Type | Required | Description | Example | | ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ | -| `company_id` | *str* | :heavy_check_mark: | N/A | 8a210b68-6988-11ed-a1eb-0242ac120002 | \ No newline at end of file +| `company_id` | *str* | :heavy_check_mark: | Unique identifier for a company. | 8a210b68-6988-11ed-a1eb-0242ac120002 | \ No newline at end of file diff --git a/previous-versions/files/docs/models/operations/listfilesresponse.md b/previous-versions/files/docs/models/operations/listfilesresponse.md index 412d61f5a..4d6758307 100755 --- a/previous-versions/files/docs/models/operations/listfilesresponse.md +++ b/previous-versions/files/docs/models/operations/listfilesresponse.md @@ -3,10 +3,11 @@ ## Fields -| Field | Type | Required | Description | -| ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -| `content_type` | *str* | :heavy_check_mark: | N/A | -| `error_message` | [Optional[shared.ErrorMessage]](../../models/shared/errormessage.md) | :heavy_minus_sign: | Your API request was not properly authorized. | -| `files` | list[[shared.File](../../models/shared/file.md)] | :heavy_minus_sign: | Success | -| `status_code` | *int* | :heavy_check_mark: | N/A | -| `raw_response` | [requests.Response](https://requests.readthedocs.io/en/latest/api/#requests.Response) | :heavy_minus_sign: | N/A | \ No newline at end of file +| Field | Type | Required | Description | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `content_type` | *str* | :heavy_check_mark: | HTTP response content type for this operation | +| `error_message` | [Optional[ListFilesErrorMessage]](../../models/operations/listfileserrormessage.md) | :heavy_minus_sign: | One or more of the resources you referenced could not be found.
This might be because your company or data connection id is wrong, or was already deleted. | +| `files` | List[[shared.File](../../models/shared/file.md)] | :heavy_minus_sign: | Success | +| `status_code` | *int* | :heavy_check_mark: | HTTP response status code for this operation | +| `raw_response` | [requests.Response](https://requests.readthedocs.io/en/latest/api/#requests.Response) | :heavy_minus_sign: | Raw HTTP response; suitable for custom response parsing | +| `schema` | [Optional[shared.Schema]](../../models/shared/schema.md) | :heavy_minus_sign: | Your API request was not properly authorized. | \ No newline at end of file diff --git a/previous-versions/files/docs/models/operations/uploadfileserrormessage.md b/previous-versions/files/docs/models/operations/uploadfileserrormessage.md new file mode 100755 index 000000000..c7c87f28f --- /dev/null +++ b/previous-versions/files/docs/models/operations/uploadfileserrormessage.md @@ -0,0 +1,16 @@ +# UploadFilesErrorMessage + +One or more of the resources you referenced could not be found. +This might be because your company or data connection id is wrong, or was already deleted. + + +## Fields + +| Field | Type | Required | Description | +| ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `can_be_retried` | *Optional[str]* | :heavy_minus_sign: | `True` if the error occurred transiently and can be retried. | +| `correlation_id` | *Optional[str]* | :heavy_minus_sign: | Unique identifier used to propagate to all downstream services and determine the source of the error. | +| `detailed_error_code` | *Optional[int]* | :heavy_minus_sign: | Machine readable error code used to automate processes based on the code returned. | +| `error` | *Optional[str]* | :heavy_minus_sign: | A brief description of the error. | +| `service` | *Optional[str]* | :heavy_minus_sign: | Codat's service the returned the error. | +| `status_code` | *Optional[int]* | :heavy_minus_sign: | The HTTP status code returned by the error. | \ No newline at end of file diff --git a/previous-versions/files/docs/models/operations/uploadfilesrequest.md b/previous-versions/files/docs/models/operations/uploadfilesrequest.md index 3d98cc629..3894d4295 100755 --- a/previous-versions/files/docs/models/operations/uploadfilesrequest.md +++ b/previous-versions/files/docs/models/operations/uploadfilesrequest.md @@ -6,5 +6,5 @@ | Field | Type | Required | Description | Example | | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | | `request_body` | [Optional[UploadFilesRequestBody]](../../models/operations/uploadfilesrequestbody.md) | :heavy_minus_sign: | N/A | | -| `company_id` | *str* | :heavy_check_mark: | N/A | 8a210b68-6988-11ed-a1eb-0242ac120002 | -| `connection_id` | *str* | :heavy_check_mark: | N/A | 2e9d2c44-f675-40ba-8049-353bfcb5e171 | \ No newline at end of file +| `company_id` | *str* | :heavy_check_mark: | Unique identifier for a company. | 8a210b68-6988-11ed-a1eb-0242ac120002 | +| `connection_id` | *str* | :heavy_check_mark: | Unique identifier for a connection. | 2e9d2c44-f675-40ba-8049-353bfcb5e171 | \ No newline at end of file diff --git a/previous-versions/files/docs/models/operations/uploadfilesresponse.md b/previous-versions/files/docs/models/operations/uploadfilesresponse.md index dd258b538..6e80242f9 100755 --- a/previous-versions/files/docs/models/operations/uploadfilesresponse.md +++ b/previous-versions/files/docs/models/operations/uploadfilesresponse.md @@ -3,9 +3,10 @@ ## Fields -| Field | Type | Required | Description | -| ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -| `content_type` | *str* | :heavy_check_mark: | N/A | -| `error_message` | [Optional[shared.ErrorMessage]](../../models/shared/errormessage.md) | :heavy_minus_sign: | The request made is not valid. | -| `status_code` | *int* | :heavy_check_mark: | N/A | -| `raw_response` | [requests.Response](https://requests.readthedocs.io/en/latest/api/#requests.Response) | :heavy_minus_sign: | N/A | \ No newline at end of file +| Field | Type | Required | Description | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `content_type` | *str* | :heavy_check_mark: | HTTP response content type for this operation | +| `error_message` | [Optional[UploadFilesErrorMessage]](../../models/operations/uploadfileserrormessage.md) | :heavy_minus_sign: | One or more of the resources you referenced could not be found.
This might be because your company or data connection id is wrong, or was already deleted. | +| `status_code` | *int* | :heavy_check_mark: | HTTP response status code for this operation | +| `raw_response` | [requests.Response](https://requests.readthedocs.io/en/latest/api/#requests.Response) | :heavy_minus_sign: | Raw HTTP response; suitable for custom response parsing | +| `schema` | [Optional[shared.Schema]](../../models/shared/schema.md) | :heavy_minus_sign: | The request made is not valid. | \ No newline at end of file diff --git a/previous-versions/files/docs/models/shared/errormessage.md b/previous-versions/files/docs/models/shared/errormessage.md deleted file mode 100755 index 6ec4e95a4..000000000 --- a/previous-versions/files/docs/models/shared/errormessage.md +++ /dev/null @@ -1,15 +0,0 @@ -# ErrorMessage - -The request made is not valid. - - -## Fields - -| Field | Type | Required | Description | -| --------------------- | --------------------- | --------------------- | --------------------- | -| `can_be_retried` | *Optional[str]* | :heavy_minus_sign: | N/A | -| `correlation_id` | *Optional[str]* | :heavy_minus_sign: | N/A | -| `detailed_error_code` | *Optional[int]* | :heavy_minus_sign: | N/A | -| `error` | *Optional[str]* | :heavy_minus_sign: | N/A | -| `service` | *Optional[str]* | :heavy_minus_sign: | N/A | -| `status_code` | *Optional[int]* | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/previous-versions/files/docs/models/shared/file.md b/previous-versions/files/docs/models/shared/file.md index 733fb778f..0231c4b4a 100755 --- a/previous-versions/files/docs/models/shared/file.md +++ b/previous-versions/files/docs/models/shared/file.md @@ -5,7 +5,7 @@ | Field | Type | Required | Description | Example | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `display_name` | *Optional[str]* | :heavy_minus_sign: | N/A | | -| `file_name` | *Optional[str]* | :heavy_minus_sign: | N/A | | -| `source_type` | *Optional[str]* | :heavy_minus_sign: | N/A | | +| `display_name` | *Optional[str]* | :heavy_minus_sign: | An optional display name for the file. | | +| `file_name` | *Optional[str]* | :heavy_minus_sign: | The file's name. | | +| `source_type` | *Optional[str]* | :heavy_minus_sign: | The source of the file uploaded. | | | `uploaded` | *Optional[str]* | :heavy_minus_sign: | In Codat's data model, dates and times are represented using the ISO 8601 standard. Date and time fields are formatted as strings; for example:

```
2020-10-08T22:40:50Z
2021-01-01T00:00:00
```



When syncing data that contains `DateTime` fields from Codat, make sure you support the following cases when reading time information:

- Coordinated Universal Time (UTC): `2021-11-15T06:00:00Z`
- Unqualified local time: `2021-11-15T01:00:00`
- UTC time offsets: `2021-11-15T01:00:00-05:00`

> Time zones
>
> Not all dates from Codat will contain information about time zones.
> Where it is not available from the underlying platform, Codat will return these as times local to the business whose data has been synced. | 2022-10-23T00:00:00.000Z | \ No newline at end of file diff --git a/previous-versions/files/docs/models/shared/schema.md b/previous-versions/files/docs/models/shared/schema.md new file mode 100755 index 000000000..c7b33b0db --- /dev/null +++ b/previous-versions/files/docs/models/shared/schema.md @@ -0,0 +1,13 @@ +# Schema + + +## Fields + +| Field | Type | Required | Description | +| ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `can_be_retried` | *Optional[str]* | :heavy_minus_sign: | `True` if the error occurred transiently and can be retried. | +| `correlation_id` | *Optional[str]* | :heavy_minus_sign: | Unique identifier used to propagate to all downstream services and determine the source of the error. | +| `detailed_error_code` | *Optional[int]* | :heavy_minus_sign: | Machine readable error code used to automate processes based on the code returned. | +| `error` | *Optional[str]* | :heavy_minus_sign: | A brief description of the error. | +| `service` | *Optional[str]* | :heavy_minus_sign: | Codat's service the returned the error. | +| `status_code` | *Optional[int]* | :heavy_minus_sign: | The HTTP status code returned by the error. | \ No newline at end of file diff --git a/previous-versions/files/docs/sdks/codatfiles/README.md b/previous-versions/files/docs/sdks/codatfiles/README.md index c3c64ff8f..a965e16ae 100755 --- a/previous-versions/files/docs/sdks/codatfiles/README.md +++ b/previous-versions/files/docs/sdks/codatfiles/README.md @@ -1,5 +1,6 @@ # CodatFiles SDK + ## Overview Files API: A flexible API for pulling accounting data, normalized and aggregated from 20 accounting integrations. diff --git a/previous-versions/files/docs/sdks/files/README.md b/previous-versions/files/docs/sdks/files/README.md index ca448b172..ec92b4340 100755 --- a/previous-versions/files/docs/sdks/files/README.md +++ b/previous-versions/files/docs/sdks/files/README.md @@ -1,4 +1,5 @@ -# files +# Files +(*files*) ## Overview @@ -21,9 +22,7 @@ import codatfiles from codatfiles.models import operations, shared s = codatfiles.CodatFiles( - security=shared.Security( - auth_header="Basic BASE_64_ENCODED(API_KEY)", - ), + auth_header="Basic BASE_64_ENCODED(API_KEY)", ) req = operations.DownloadFilesRequest( @@ -35,6 +34,7 @@ res = s.files.download_files(req) if res.data is not None: # handle response + pass ``` ### Parameters @@ -61,9 +61,7 @@ import codatfiles from codatfiles.models import operations, shared s = codatfiles.CodatFiles( - security=shared.Security( - auth_header="Basic BASE_64_ENCODED(API_KEY)", - ), + auth_header="Basic BASE_64_ENCODED(API_KEY)", ) req = operations.ListFilesRequest( @@ -74,6 +72,7 @@ res = s.files.list_files(req) if res.files is not None: # handle response + pass ``` ### Parameters @@ -106,15 +105,13 @@ import codatfiles from codatfiles.models import operations, shared s = codatfiles.CodatFiles( - security=shared.Security( - auth_header="Basic BASE_64_ENCODED(API_KEY)", - ), + auth_header="Basic BASE_64_ENCODED(API_KEY)", ) req = operations.UploadFilesRequest( request_body=operations.UploadFilesRequestBody( - content='distinctio'.encode(), - request_body='quibusdam', + content=';*>\'Oq[l/G'.encode(), + request_body='syndicate Central defect', ), company_id='8a210b68-6988-11ed-a1eb-0242ac120002', connection_id='2e9d2c44-f675-40ba-8049-353bfcb5e171', @@ -124,6 +121,7 @@ res = s.files.upload_files(req) if res.status_code == 200: # handle response + pass ``` ### Parameters diff --git a/previous-versions/files/files.gen b/previous-versions/files/files.gen index 3214d4b6a..c38dc0d1c 100755 --- a/previous-versions/files/files.gen +++ b/previous-versions/files/files.gen @@ -13,23 +13,26 @@ src/codatfiles/models/operations/download_files.py src/codatfiles/models/operations/list_files.py src/codatfiles/models/operations/upload_files.py src/codatfiles/models/operations/__init__.py -src/codatfiles/models/shared/errormessage.py +src/codatfiles/models/shared/schema.py src/codatfiles/models/shared/file.py src/codatfiles/models/shared/security.py src/codatfiles/models/shared/__init__.py src/codatfiles/models/errors/__init__.py -docs/sdks/codatfiles/README.md -docs/models/utils/retryconfig.md -docs/sdks/files/README.md USAGE.md docs/models/operations/downloadfilesrequest.md +docs/models/operations/downloadfileserrormessage.md docs/models/operations/downloadfilesresponse.md docs/models/operations/listfilesrequest.md +docs/models/operations/listfileserrormessage.md docs/models/operations/listfilesresponse.md docs/models/operations/uploadfilesrequestbody.md docs/models/operations/uploadfilesrequest.md +docs/models/operations/uploadfileserrormessage.md docs/models/operations/uploadfilesresponse.md -docs/models/shared/errormessage.md +docs/models/shared/schema.md docs/models/shared/file.md docs/models/shared/security.md +docs/sdks/codatfiles/README.md +docs/models/utils/retryconfig.md +docs/sdks/files/README.md .gitattributes \ No newline at end of file diff --git a/previous-versions/files/gen.yaml b/previous-versions/files/gen.yaml index 149fa03ad..3df23c0d7 100644 --- a/previous-versions/files/gen.yaml +++ b/previous-versions/files/gen.yaml @@ -1,16 +1,25 @@ configVersion: 1.0.0 management: - docChecksum: '00000000000000000000000000000000' - docVersion: 2.1.0 - speakeasyVersion: 1.53.0 - generationVersion: 2.58.0 + docChecksum: 51ee4fbc6a66709c22663c007999f4b3 + docVersion: 3.0.0 + speakeasyVersion: 1.100.2 + generationVersion: 2.159.2 generation: sdkClassName: CodatFiles singleTagPerOp: false telemetryEnabled: true +features: + python: + core: 3.0.2 + downloadStreams: 0.0.1 + examples: 2.81.2 + globalSecurity: 2.82.0 + globalServerURLs: 2.82.0 + retries: 2.82.0 python: - version: 0.0.0 + version: 0.1.0 author: Codat description: Use Codat's Files API to upload your SMB customers' files. + flattenGlobalSecurity: true maxMethodParams: 0 packageName: codat-files diff --git a/previous-versions/files/pylintrc b/previous-versions/files/pylintrc index 8307335ef..d5760436d 100755 --- a/previous-versions/files/pylintrc +++ b/previous-versions/files/pylintrc @@ -88,7 +88,7 @@ persistent=yes # Minimum Python version to use for version dependent checks. Will default to # the version used to run pylint. -py-version=3.9 +py-version=3.8 # Discover python modules and packages in the file system subtree. recursive=no @@ -116,12 +116,12 @@ argument-naming-style=snake_case #argument-rgx= # Naming style matching correct attribute names. -attr-naming-style=snake_case +#attr-naming-style=snake_case # Regular expression matching correct attribute names. Overrides attr-naming- # style. If left empty, attribute names will be checked with the set naming # style. -#attr-rgx= +attr-rgx=[^\W\d][^\W]*|__.*__$ # Bad variable names which should always be refused, separated by a comma. bad-names= diff --git a/previous-versions/files/setup.py b/previous-versions/files/setup.py index 8ac166b96..23180c508 100755 --- a/previous-versions/files/setup.py +++ b/previous-versions/files/setup.py @@ -17,26 +17,24 @@ long_description_content_type="text/markdown", packages=setuptools.find_packages(where="src"), install_requires=[ - "certifi>=2022.12.7", - "charset-normalizer>=2.1.1", - "dataclasses-json>=0.5.12", - "idna>=3.3", + "certifi>=2023.7.22", + "charset-normalizer>=3.2.0", + "dataclasses-json>=0.6.1", + "idna>=3.4", "jsonpath-python>=1.0.6 ", - "marshmallow>=3.17.1", - "marshmallow-enum>=1.5.1", - "mypy-extensions>=0.4.3", - "packaging>=21.3", - "pyparsing>=3.0.9", + "marshmallow>=3.19.0", + "mypy-extensions>=1.0.0", + "packaging>=23.1", "python-dateutil>=2.8.2", - "requests>=2.28.1", + "requests>=2.31.0", "six>=1.16.0", - "typing-inspect>=0.8.0", - "typing_extensions>=4.3.0", - "urllib3>=1.26.12", + "typing-inspect>=0.9.0", + "typing_extensions>=4.7.1", + "urllib3>=2.0.4", ], extras_require={ "dev":["pylint==2.16.2"] }, package_dir={'': 'src'}, - python_requires='>=3.9' + python_requires='>=3.8' ) diff --git a/previous-versions/files/src/codatfiles/files.py b/previous-versions/files/src/codatfiles/files.py index 0cbc3a239..6811732a9 100755 --- a/previous-versions/files/src/codatfiles/files.py +++ b/previous-versions/files/src/codatfiles/files.py @@ -4,7 +4,7 @@ from codatfiles import utils from codatfiles.models import errors, operations, shared from enum import Enum -from typing import Optional +from typing import List, Optional class DownloadFilesAcceptEnum(str, Enum): APPLICATION_JSON = "application/json" @@ -31,17 +31,21 @@ def download_files(self, request: operations.DownloadFilesRequest, retries: Opti headers['Accept'] = accept_header_override.value else: headers['Accept'] = 'application/json;q=1, application/octet-stream;q=0' - headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' + headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.security_client + global_retry_config = self.sdk_configuration.retry_config retry_config = retries if retry_config is None: - retry_config = utils.RetryConfig('backoff', utils.BackoffStrategy(500, 60000, 1.5, 3600000), True) + if global_retry_config: + retry_config = global_retry_config + else: + retry_config = utils.RetryConfig('backoff', utils.BackoffStrategy(500, 60000, 1.5, 3600000), True) def do_request(): return client.request('GET', url, params=query_params, headers=headers) - + http_res = utils.retry(do_request, utils.Retries(retry_config, [ '408', '429', @@ -53,12 +57,18 @@ def do_request(): if http_res.status_code == 200: if utils.match_content_type(content_type, 'application/octet-stream'): - res.data = http_res.content + res.data = http_res else: raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res) - elif http_res.status_code in [400, 401, 404, 429]: + elif http_res.status_code in [400, 401, 429]: if utils.match_content_type(content_type, 'application/json'): - out = utils.unmarshal_json(http_res.text, Optional[shared.ErrorMessage]) + out = utils.unmarshal_json(http_res.text, Optional[shared.Schema]) + res.schema = out + else: + raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res) + elif http_res.status_code == 404: + if utils.match_content_type(content_type, 'application/json'): + out = utils.unmarshal_json(http_res.text, Optional[operations.DownloadFilesErrorMessage]) res.error_message = out else: raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res) @@ -75,17 +85,21 @@ def list_files(self, request: operations.ListFilesRequest, retries: Optional[uti url = utils.generate_url(operations.ListFilesRequest, base_url, '/companies/{companyId}/files', request) headers = {} headers['Accept'] = 'application/json' - headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' + headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.security_client + global_retry_config = self.sdk_configuration.retry_config retry_config = retries if retry_config is None: - retry_config = utils.RetryConfig('backoff', utils.BackoffStrategy(500, 60000, 1.5, 3600000), True) + if global_retry_config: + retry_config = global_retry_config + else: + retry_config = utils.RetryConfig('backoff', utils.BackoffStrategy(500, 60000, 1.5, 3600000), True) def do_request(): return client.request('GET', url, headers=headers) - + http_res = utils.retry(do_request, utils.Retries(retry_config, [ '408', '429', @@ -97,13 +111,19 @@ def do_request(): if http_res.status_code == 200: if utils.match_content_type(content_type, 'application/json'): - out = utils.unmarshal_json(http_res.text, Optional[list[shared.File]]) + out = utils.unmarshal_json(http_res.text, Optional[List[shared.File]]) res.files = out else: raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res) - elif http_res.status_code in [401, 404, 429]: + elif http_res.status_code in [401, 429]: if utils.match_content_type(content_type, 'application/json'): - out = utils.unmarshal_json(http_res.text, Optional[shared.ErrorMessage]) + out = utils.unmarshal_json(http_res.text, Optional[shared.Schema]) + res.schema = out + else: + raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res) + elif http_res.status_code == 404: + if utils.match_content_type(content_type, 'application/json'): + out = utils.unmarshal_json(http_res.text, Optional[operations.ListFilesErrorMessage]) res.error_message = out else: raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res) @@ -125,21 +145,25 @@ def upload_files(self, request: operations.UploadFilesRequest, retries: Optional url = utils.generate_url(operations.UploadFilesRequest, base_url, '/companies/{companyId}/connections/{connectionId}/files', request) headers = {} - req_content_type, data, form = utils.serialize_request_body(request, "request_body", 'multipart') + req_content_type, data, form = utils.serialize_request_body(request, "request_body", False, True, 'multipart') if req_content_type not in ('multipart/form-data', 'multipart/mixed'): headers['content-type'] = req_content_type headers['Accept'] = 'application/json' - headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' + headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.security_client + global_retry_config = self.sdk_configuration.retry_config retry_config = retries if retry_config is None: - retry_config = utils.RetryConfig('backoff', utils.BackoffStrategy(500, 60000, 1.5, 3600000), True) + if global_retry_config: + retry_config = global_retry_config + else: + retry_config = utils.RetryConfig('backoff', utils.BackoffStrategy(500, 60000, 1.5, 3600000), True) def do_request(): return client.request('POST', url, data=data, files=form, headers=headers) - + http_res = utils.retry(do_request, utils.Retries(retry_config, [ '408', '429', @@ -151,9 +175,15 @@ def do_request(): if http_res.status_code == 200: pass - elif http_res.status_code in [400, 401, 404, 429]: + elif http_res.status_code in [400, 401, 429]: + if utils.match_content_type(content_type, 'application/json'): + out = utils.unmarshal_json(http_res.text, Optional[shared.Schema]) + res.schema = out + else: + raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res) + elif http_res.status_code == 404: if utils.match_content_type(content_type, 'application/json'): - out = utils.unmarshal_json(http_res.text, Optional[shared.ErrorMessage]) + out = utils.unmarshal_json(http_res.text, Optional[operations.UploadFilesErrorMessage]) res.error_message = out else: raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res) diff --git a/previous-versions/files/src/codatfiles/models/__init__.py b/previous-versions/files/src/codatfiles/models/__init__.py index 889f8adcf..36628d6cc 100755 --- a/previous-versions/files/src/codatfiles/models/__init__.py +++ b/previous-versions/files/src/codatfiles/models/__init__.py @@ -1,2 +1,3 @@ """Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" +# __init__.py diff --git a/previous-versions/files/src/codatfiles/models/operations/__init__.py b/previous-versions/files/src/codatfiles/models/operations/__init__.py index b3e7ba36e..550e8b30a 100755 --- a/previous-versions/files/src/codatfiles/models/operations/__init__.py +++ b/previous-versions/files/src/codatfiles/models/operations/__init__.py @@ -4,4 +4,4 @@ from .list_files import * from .upload_files import * -__all__ = ["DownloadFilesRequest","DownloadFilesResponse","ListFilesRequest","ListFilesResponse","UploadFilesRequest","UploadFilesRequestBody","UploadFilesResponse"] +__all__ = ["DownloadFilesErrorMessage","DownloadFilesRequest","DownloadFilesResponse","ListFilesErrorMessage","ListFilesRequest","ListFilesResponse","UploadFilesErrorMessage","UploadFilesRequest","UploadFilesRequestBody","UploadFilesResponse"] diff --git a/previous-versions/files/src/codatfiles/models/operations/download_files.py b/previous-versions/files/src/codatfiles/models/operations/download_files.py index cf3b76372..da0a7ae5e 100755 --- a/previous-versions/files/src/codatfiles/models/operations/download_files.py +++ b/previous-versions/files/src/codatfiles/models/operations/download_files.py @@ -3,29 +3,59 @@ from __future__ import annotations import dataclasses import requests as requests_http -from ..shared import errormessage as shared_errormessage +from ..shared import schema as shared_schema +from codatfiles import utils +from dataclasses_json import Undefined, dataclass_json from typing import Optional - @dataclasses.dataclass class DownloadFilesRequest: company_id: str = dataclasses.field(metadata={'path_param': { 'field_name': 'companyId', 'style': 'simple', 'explode': False }}) + r"""Unique identifier for a company.""" date_: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'date', 'style': 'form', 'explode': True }}) r"""Only download files uploaded on this date.""" +@dataclass_json(undefined=Undefined.EXCLUDE) +@dataclasses.dataclass +class DownloadFilesErrorMessage: + r"""One or more of the resources you referenced could not be found. + This might be because your company or data connection id is wrong, or was already deleted. + """ + can_be_retried: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('canBeRetried'), 'exclude': lambda f: f is None }}) + r"""`True` if the error occurred transiently and can be retried.""" + correlation_id: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('correlationId'), 'exclude': lambda f: f is None }}) + r"""Unique identifier used to propagate to all downstream services and determine the source of the error.""" + detailed_error_code: Optional[int] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('detailedErrorCode'), 'exclude': lambda f: f is None }}) + r"""Machine readable error code used to automate processes based on the code returned.""" + error: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('error'), 'exclude': lambda f: f is None }}) + r"""A brief description of the error.""" + service: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('service'), 'exclude': lambda f: f is None }}) + r"""Codat's service the returned the error.""" + status_code: Optional[int] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('statusCode'), 'exclude': lambda f: f is None }}) + r"""The HTTP status code returned by the error.""" + + + @dataclasses.dataclass class DownloadFilesResponse: content_type: str = dataclasses.field() + r"""HTTP response content type for this operation""" status_code: int = dataclasses.field() - data: Optional[bytes] = dataclasses.field(default=None) + r"""HTTP response status code for this operation""" + data: Optional[requests_http.Response] = dataclasses.field(default=None) r"""Success""" - error_message: Optional[shared_errormessage.ErrorMessage] = dataclasses.field(default=None) - r"""The request made is not valid.""" + error_message: Optional[DownloadFilesErrorMessage] = dataclasses.field(default=None) + r"""One or more of the resources you referenced could not be found. + This might be because your company or data connection id is wrong, or was already deleted. + """ raw_response: Optional[requests_http.Response] = dataclasses.field(default=None) + r"""Raw HTTP response; suitable for custom response parsing""" + schema: Optional[shared_schema.Schema] = dataclasses.field(default=None) + r"""The request made is not valid.""" diff --git a/previous-versions/files/src/codatfiles/models/operations/list_files.py b/previous-versions/files/src/codatfiles/models/operations/list_files.py index 12fdcd704..f364b6f09 100755 --- a/previous-versions/files/src/codatfiles/models/operations/list_files.py +++ b/previous-versions/files/src/codatfiles/models/operations/list_files.py @@ -3,28 +3,58 @@ from __future__ import annotations import dataclasses import requests as requests_http -from ..shared import errormessage as shared_errormessage from ..shared import file as shared_file -from typing import Optional - +from ..shared import schema as shared_schema +from codatfiles import utils +from dataclasses_json import Undefined, dataclass_json +from typing import List, Optional @dataclasses.dataclass class ListFilesRequest: company_id: str = dataclasses.field(metadata={'path_param': { 'field_name': 'companyId', 'style': 'simple', 'explode': False }}) + r"""Unique identifier for a company.""" +@dataclass_json(undefined=Undefined.EXCLUDE) +@dataclasses.dataclass +class ListFilesErrorMessage: + r"""One or more of the resources you referenced could not be found. + This might be because your company or data connection id is wrong, or was already deleted. + """ + can_be_retried: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('canBeRetried'), 'exclude': lambda f: f is None }}) + r"""`True` if the error occurred transiently and can be retried.""" + correlation_id: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('correlationId'), 'exclude': lambda f: f is None }}) + r"""Unique identifier used to propagate to all downstream services and determine the source of the error.""" + detailed_error_code: Optional[int] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('detailedErrorCode'), 'exclude': lambda f: f is None }}) + r"""Machine readable error code used to automate processes based on the code returned.""" + error: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('error'), 'exclude': lambda f: f is None }}) + r"""A brief description of the error.""" + service: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('service'), 'exclude': lambda f: f is None }}) + r"""Codat's service the returned the error.""" + status_code: Optional[int] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('statusCode'), 'exclude': lambda f: f is None }}) + r"""The HTTP status code returned by the error.""" + + + @dataclasses.dataclass class ListFilesResponse: content_type: str = dataclasses.field() + r"""HTTP response content type for this operation""" status_code: int = dataclasses.field() - error_message: Optional[shared_errormessage.ErrorMessage] = dataclasses.field(default=None) - r"""Your API request was not properly authorized.""" - files: Optional[list[shared_file.File]] = dataclasses.field(default=None) + r"""HTTP response status code for this operation""" + error_message: Optional[ListFilesErrorMessage] = dataclasses.field(default=None) + r"""One or more of the resources you referenced could not be found. + This might be because your company or data connection id is wrong, or was already deleted. + """ + files: Optional[List[shared_file.File]] = dataclasses.field(default=None) r"""Success""" raw_response: Optional[requests_http.Response] = dataclasses.field(default=None) + r"""Raw HTTP response; suitable for custom response parsing""" + schema: Optional[shared_schema.Schema] = dataclasses.field(default=None) + r"""Your API request was not properly authorized.""" diff --git a/previous-versions/files/src/codatfiles/models/operations/upload_files.py b/previous-versions/files/src/codatfiles/models/operations/upload_files.py index e5338d3ca..63ff5bdb7 100755 --- a/previous-versions/files/src/codatfiles/models/operations/upload_files.py +++ b/previous-versions/files/src/codatfiles/models/operations/upload_files.py @@ -3,11 +3,12 @@ from __future__ import annotations import dataclasses import requests as requests_http -from ..shared import errormessage as shared_errormessage +from ..shared import schema as shared_schema +from codatfiles import utils +from dataclasses_json import Undefined, dataclass_json from typing import Optional - @dataclasses.dataclass class UploadFilesRequestBody: content: bytes = dataclasses.field(metadata={'multipart_form': { 'content': True }}) @@ -16,23 +17,52 @@ class UploadFilesRequestBody: - @dataclasses.dataclass class UploadFilesRequest: company_id: str = dataclasses.field(metadata={'path_param': { 'field_name': 'companyId', 'style': 'simple', 'explode': False }}) + r"""Unique identifier for a company.""" connection_id: str = dataclasses.field(metadata={'path_param': { 'field_name': 'connectionId', 'style': 'simple', 'explode': False }}) + r"""Unique identifier for a connection.""" request_body: Optional[UploadFilesRequestBody] = dataclasses.field(default=None, metadata={'multipart_form': { 'file': True }, 'request': { 'media_type': 'multipart/form-data' }}) +@dataclass_json(undefined=Undefined.EXCLUDE) +@dataclasses.dataclass +class UploadFilesErrorMessage: + r"""One or more of the resources you referenced could not be found. + This might be because your company or data connection id is wrong, or was already deleted. + """ + can_be_retried: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('canBeRetried'), 'exclude': lambda f: f is None }}) + r"""`True` if the error occurred transiently and can be retried.""" + correlation_id: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('correlationId'), 'exclude': lambda f: f is None }}) + r"""Unique identifier used to propagate to all downstream services and determine the source of the error.""" + detailed_error_code: Optional[int] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('detailedErrorCode'), 'exclude': lambda f: f is None }}) + r"""Machine readable error code used to automate processes based on the code returned.""" + error: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('error'), 'exclude': lambda f: f is None }}) + r"""A brief description of the error.""" + service: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('service'), 'exclude': lambda f: f is None }}) + r"""Codat's service the returned the error.""" + status_code: Optional[int] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('statusCode'), 'exclude': lambda f: f is None }}) + r"""The HTTP status code returned by the error.""" + + + @dataclasses.dataclass class UploadFilesResponse: content_type: str = dataclasses.field() + r"""HTTP response content type for this operation""" status_code: int = dataclasses.field() - error_message: Optional[shared_errormessage.ErrorMessage] = dataclasses.field(default=None) - r"""The request made is not valid.""" + r"""HTTP response status code for this operation""" + error_message: Optional[UploadFilesErrorMessage] = dataclasses.field(default=None) + r"""One or more of the resources you referenced could not be found. + This might be because your company or data connection id is wrong, or was already deleted. + """ raw_response: Optional[requests_http.Response] = dataclasses.field(default=None) + r"""Raw HTTP response; suitable for custom response parsing""" + schema: Optional[shared_schema.Schema] = dataclasses.field(default=None) + r"""The request made is not valid.""" diff --git a/previous-versions/files/src/codatfiles/models/shared/__init__.py b/previous-versions/files/src/codatfiles/models/shared/__init__.py index 9af1da269..e39d1ca41 100755 --- a/previous-versions/files/src/codatfiles/models/shared/__init__.py +++ b/previous-versions/files/src/codatfiles/models/shared/__init__.py @@ -1,7 +1,7 @@ """Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" -from .errormessage import * from .file import * +from .schema import * from .security import * -__all__ = ["ErrorMessage","File","Security"] +__all__ = ["File","Schema","Security"] diff --git a/previous-versions/files/src/codatfiles/models/shared/file.py b/previous-versions/files/src/codatfiles/models/shared/file.py index 5075ad5fc..643128f56 100755 --- a/previous-versions/files/src/codatfiles/models/shared/file.py +++ b/previous-versions/files/src/codatfiles/models/shared/file.py @@ -8,12 +8,14 @@ @dataclass_json(undefined=Undefined.EXCLUDE) - @dataclasses.dataclass class File: - display_name: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('displayName'), 'exclude': lambda f: f is None }}) - file_name: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('fileName'), 'exclude': lambda f: f is None }}) - source_type: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('sourceType'), 'exclude': lambda f: f is None }}) + display_name: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('displayName') }}) + r"""An optional display name for the file.""" + file_name: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('fileName') }}) + r"""The file's name.""" + source_type: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('sourceType') }}) + r"""The source of the file uploaded.""" uploaded: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('uploaded'), 'exclude': lambda f: f is None }}) r"""In Codat's data model, dates and times are represented using the ISO 8601 standard. Date and time fields are formatted as strings; for example: diff --git a/previous-versions/files/src/codatfiles/models/shared/errormessage.py b/previous-versions/files/src/codatfiles/models/shared/schema.py similarity index 76% rename from previous-versions/files/src/codatfiles/models/shared/errormessage.py rename to previous-versions/files/src/codatfiles/models/shared/schema.py index f6498cc65..43540dabd 100755 --- a/previous-versions/files/src/codatfiles/models/shared/errormessage.py +++ b/previous-versions/files/src/codatfiles/models/shared/schema.py @@ -8,15 +8,19 @@ @dataclass_json(undefined=Undefined.EXCLUDE) - @dataclasses.dataclass -class ErrorMessage: - r"""The request made is not valid.""" +class Schema: can_be_retried: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('canBeRetried'), 'exclude': lambda f: f is None }}) + r"""`True` if the error occurred transiently and can be retried.""" correlation_id: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('correlationId'), 'exclude': lambda f: f is None }}) + r"""Unique identifier used to propagate to all downstream services and determine the source of the error.""" detailed_error_code: Optional[int] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('detailedErrorCode'), 'exclude': lambda f: f is None }}) + r"""Machine readable error code used to automate processes based on the code returned.""" error: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('error'), 'exclude': lambda f: f is None }}) + r"""A brief description of the error.""" service: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('service'), 'exclude': lambda f: f is None }}) + r"""Codat's service the returned the error.""" status_code: Optional[int] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('statusCode'), 'exclude': lambda f: f is None }}) + r"""The HTTP status code returned by the error.""" diff --git a/previous-versions/files/src/codatfiles/models/shared/security.py b/previous-versions/files/src/codatfiles/models/shared/security.py index a72246378..1d57f5faa 100755 --- a/previous-versions/files/src/codatfiles/models/shared/security.py +++ b/previous-versions/files/src/codatfiles/models/shared/security.py @@ -4,7 +4,6 @@ import dataclasses - @dataclasses.dataclass class Security: auth_header: str = dataclasses.field(metadata={'security': { 'scheme': True, 'type': 'apiKey', 'sub_type': 'header', 'field_name': 'Authorization' }}) diff --git a/previous-versions/files/src/codatfiles/sdk.py b/previous-versions/files/src/codatfiles/sdk.py index 2b555cb34..2d6dd62d8 100755 --- a/previous-versions/files/src/codatfiles/sdk.py +++ b/previous-versions/files/src/codatfiles/sdk.py @@ -5,6 +5,7 @@ from .sdkconfiguration import SDKConfiguration from codatfiles import utils from codatfiles.models import shared +from typing import Dict class CodatFiles: r"""Files API: A flexible API for pulling accounting data, normalized and aggregated from 20 accounting integrations. @@ -21,35 +22,40 @@ class CodatFiles: sdk_configuration: SDKConfiguration def __init__(self, - security: shared.Security = None, + auth_header: str, server_idx: int = None, server_url: str = None, - url_params: dict[str, str] = None, - client: requests_http.Session = None + url_params: Dict[str, str] = None, + client: requests_http.Session = None, + retry_config: utils.RetryConfig = None ) -> None: """Instantiates the SDK configuring it with the provided parameters. - :param security: The security details required for authentication - :type security: shared.Security + :param auth_header: The auth_header required for authentication + :type auth_header: str :param server_idx: The index of the server to use for all operations :type server_idx: int :param server_url: The server URL to use for all operations :type server_url: str :param url_params: Parameters to optionally template the server URL with - :type url_params: dict[str, str] + :type url_params: Dict[str, str] :param client: The requests.Session HTTP client to use for all operations - :type client: requests_http.Session + :type client: requests_http.Session + :param retry_config: The utils.RetryConfig to use globally + :type retry_config: utils.RetryConfig """ if client is None: client = requests_http.Session() - security_client = utils.configure_security_client(client, security) + + security_client = utils.configure_security_client(client, shared.Security(auth_header = auth_header)) + if server_url is not None: if url_params is not None: server_url = utils.template_url(server_url, url_params) - self.sdk_configuration = SDKConfiguration(client, security_client, server_url, server_idx) + self.sdk_configuration = SDKConfiguration(client, security_client, server_url, server_idx, retry_config=retry_config) self._init_sdks() diff --git a/previous-versions/files/src/codatfiles/sdkconfiguration.py b/previous-versions/files/src/codatfiles/sdkconfiguration.py index b76f7c247..346a17b19 100755 --- a/previous-versions/files/src/codatfiles/sdkconfiguration.py +++ b/previous-versions/files/src/codatfiles/sdkconfiguration.py @@ -2,6 +2,9 @@ import requests from dataclasses import dataclass +from typing import Dict, Tuple +from .utils.retries import RetryConfig +from .utils import utils SERVERS = [ @@ -19,11 +22,13 @@ class SDKConfiguration: language: str = 'python' openapi_doc_version: str = '3.0.0' sdk_version: str = '0.1.0' - gen_version: str = '2.91.4' + gen_version: str = '2.159.2' + user_agent: str = 'speakeasy-sdk/python 0.1.0 2.159.2 3.0.0 codat-files' + retry_config: RetryConfig = None - def get_server_details(self) -> tuple[str, dict[str, str]]: + def get_server_details(self) -> Tuple[str, Dict[str, str]]: if self.server_url: - return self.server_url.removesuffix('/'), {} + return utils.remove_suffix(self.server_url, '/'), {} if self.server_idx is None: self.server_idx = 0 diff --git a/previous-versions/files/src/codatfiles/utils/retries.py b/previous-versions/files/src/codatfiles/utils/retries.py index 2138c1b5e..25f49a1f2 100755 --- a/previous-versions/files/src/codatfiles/utils/retries.py +++ b/previous-versions/files/src/codatfiles/utils/retries.py @@ -2,6 +2,7 @@ import random import time +from typing import List import requests @@ -32,9 +33,9 @@ def __init__(self, strategy: str, backoff: BackoffStrategy, retry_connection_err class Retries: config: RetryConfig - status_codes: list[str] + status_codes: List[str] - def __init__(self, config: RetryConfig, status_codes: list[str]): + def __init__(self, config: RetryConfig, status_codes: List[str]): self.config = config self.status_codes = status_codes diff --git a/previous-versions/files/src/codatfiles/utils/utils.py b/previous-versions/files/src/codatfiles/utils/utils.py index ea9792d0d..ccfad9f7a 100755 --- a/previous-versions/files/src/codatfiles/utils/utils.py +++ b/previous-versions/files/src/codatfiles/utils/utils.py @@ -3,11 +3,14 @@ import base64 import json import re +import sys from dataclasses import Field, dataclass, fields, is_dataclass, make_dataclass from datetime import date, datetime +from decimal import Decimal from email.message import Message from enum import Enum -from typing import Any, Callable, Optional, Tuple, Union, get_args, get_origin +from typing import (Any, Callable, Dict, List, Optional, Tuple, Union, + get_args, get_origin) from xmlrpc.client import boolean import dateutil.parser @@ -17,14 +20,14 @@ class SecurityClient: client: requests.Session - query_params: dict[str, str] = {} + query_params: Dict[str, str] = {} def __init__(self, client: requests.Session): self.client = client def request(self, method, url, **kwargs): params = kwargs.get('params', {}) - kwargs["params"] = self.query_params | params + kwargs["params"] = {**self.query_params, **params} return self.client.request(method, url, **kwargs) @@ -67,7 +70,7 @@ def _parse_security_option(client: SecurityClient, option: dataclass): client, metadata, getattr(option, opt_field.name)) -def _parse_security_scheme(client: SecurityClient, scheme_metadata: dict, scheme: any): +def _parse_security_scheme(client: SecurityClient, scheme_metadata: Dict, scheme: any): scheme_type = scheme_metadata.get('type') sub_type = scheme_metadata.get('sub_type') @@ -91,7 +94,7 @@ def _parse_security_scheme(client: SecurityClient, scheme_metadata: dict, scheme client, scheme_metadata, scheme_metadata, scheme) -def _parse_security_scheme_value(client: SecurityClient, scheme_metadata: dict, security_metadata: dict, value: any): +def _parse_security_scheme_value(client: SecurityClient, scheme_metadata: Dict, security_metadata: Dict, value: any): scheme_type = scheme_metadata.get('type') sub_type = scheme_metadata.get('sub_type') @@ -112,7 +115,8 @@ def _parse_security_scheme_value(client: SecurityClient, scheme_metadata: dict, client.client.headers[header_name] = value elif scheme_type == 'http': if sub_type == 'bearer': - client.client.headers[header_name] = value.lower().startswith('bearer ') and value or f'Bearer {value}' + client.client.headers[header_name] = value.lower().startswith( + 'bearer ') and value or f'Bearer {value}' else: raise Exception('not supported') else: @@ -142,7 +146,7 @@ def _parse_basic_auth_scheme(client: SecurityClient, scheme: dataclass): def generate_url(clazz: type, server_url: str, path: str, path_params: dataclass, - gbls: dict[str, dict[str, dict[str, Any]]] = None) -> str: + gbls: Dict[str, Dict[str, Dict[str, Any]]] = None) -> str: path_param_fields: Tuple[Field, ...] = fields(clazz) for field in path_param_fields: request_metadata = field.metadata.get('request') @@ -171,16 +175,16 @@ def generate_url(clazz: type, server_url: str, path: str, path_params: dataclass '{' + key + '}', value, 1) else: if param_metadata.get('style', 'simple') == 'simple': - if isinstance(param, list): - pp_vals: list[str] = [] + if isinstance(param, List): + pp_vals: List[str] = [] for pp_val in param: if pp_val is None: continue pp_vals.append(_val_to_string(pp_val)) path = path.replace( '{' + param_metadata.get('field_name', field.name) + '}', ",".join(pp_vals), 1) - elif isinstance(param, dict): - pp_vals: list[str] = [] + elif isinstance(param, Dict): + pp_vals: List[str] = [] for pp_key in param: if param[pp_key] is None: continue @@ -192,8 +196,8 @@ def generate_url(clazz: type, server_url: str, path: str, path_params: dataclass f"{pp_key},{_val_to_string(param[pp_key])}") path = path.replace( '{' + param_metadata.get('field_name', field.name) + '}', ",".join(pp_vals), 1) - elif not isinstance(param, (str, int, float, complex, bool)): - pp_vals: list[str] = [] + elif not isinstance(param, (str, int, float, complex, bool, Decimal)): + pp_vals: List[str] = [] param_fields: Tuple[Field, ...] = fields(param) for param_field in param_fields: param_value_metadata = param_field.metadata.get( @@ -219,14 +223,14 @@ def generate_url(clazz: type, server_url: str, path: str, path_params: dataclass path = path.replace( '{' + param_metadata.get('field_name', field.name) + '}', _val_to_string(param), 1) - return server_url.removesuffix("/") + path + return remove_suffix(server_url, '/') + path def is_optional(field): return get_origin(field) is Union and type(None) in get_args(field) -def template_url(url_with_params: str, params: dict[str, str]) -> str: +def template_url(url_with_params: str, params: Dict[str, str]) -> str: for key, value in params.items(): url_with_params = url_with_params.replace( '{' + key + '}', value) @@ -234,9 +238,9 @@ def template_url(url_with_params: str, params: dict[str, str]) -> str: return url_with_params -def get_query_params(clazz: type, query_params: dataclass, gbls: dict[str, dict[str, dict[str, Any]]] = None) -> dict[ - str, list[str]]: - params: dict[str, list[str]] = {} +def get_query_params(clazz: type, query_params: dataclass, gbls: Dict[str, Dict[str, Dict[str, Any]]] = None) -> Dict[ + str, List[str]]: + params: Dict[str, List[str]] = {} param_fields: Tuple[Field, ...] = fields(clazz) for field in param_fields: @@ -266,24 +270,24 @@ def get_query_params(clazz: type, query_params: dataclass, gbls: dict[str, dict[ else: style = metadata.get('style', 'form') if style == 'deepObject': - params = params | _get_deep_object_query_params( - metadata, f_name, value) + params = {**params, **_get_deep_object_query_params( + metadata, f_name, value)} elif style == 'form': - params = params | _get_delimited_query_params( - metadata, f_name, value, ",") + params = {**params, **_get_delimited_query_params( + metadata, f_name, value, ",")} elif style == 'pipeDelimited': - params = params | _get_delimited_query_params( - metadata, f_name, value, "|") + params = {**params, **_get_delimited_query_params( + metadata, f_name, value, "|")} else: raise Exception('not yet implemented') return params -def get_headers(headers_params: dataclass) -> dict[str, str]: +def get_headers(headers_params: dataclass) -> Dict[str, str]: if headers_params is None: return {} - headers: dict[str, str] = {} + headers: Dict[str, str] = {} param_fields: Tuple[Field, ...] = fields(headers_params) for field in param_fields: @@ -300,8 +304,8 @@ def get_headers(headers_params: dataclass) -> dict[str, str]: return headers -def _get_serialized_params(metadata: dict, field_name: str, obj: any) -> dict[str, str]: - params: dict[str, str] = {} +def _get_serialized_params(metadata: Dict, field_name: str, obj: any) -> Dict[str, str]: + params: Dict[str, str] = {} serialization = metadata.get('serialization', '') if serialization == 'json': @@ -310,8 +314,8 @@ def _get_serialized_params(metadata: dict, field_name: str, obj: any) -> dict[st return params -def _get_deep_object_query_params(metadata: dict, field_name: str, obj: any) -> dict[str, list[str]]: - params: dict[str, list[str]] = {} +def _get_deep_object_query_params(metadata: Dict, field_name: str, obj: any) -> Dict[str, List[str]]: + params: Dict[str, List[str]] = {} if obj is None: return params @@ -327,7 +331,7 @@ def _get_deep_object_query_params(metadata: dict, field_name: str, obj: any) -> if obj_val is None: continue - if isinstance(obj_val, list): + if isinstance(obj_val, List): for val in obj_val: if val is None: continue @@ -345,12 +349,12 @@ def _get_deep_object_query_params(metadata: dict, field_name: str, obj: any) -> params[ f'{metadata.get("field_name", field_name)}[{obj_param_metadata.get("field_name", obj_field.name)}]'] = [ _val_to_string(obj_val)] - elif isinstance(obj, dict): + elif isinstance(obj, Dict): for key, value in obj.items(): if value is None: continue - if isinstance(value, list): + if isinstance(value, List): for val in value: if val is None: continue @@ -376,8 +380,8 @@ def _get_query_param_field_name(obj_field: Field) -> str: return obj_param_metadata.get("field_name", obj_field.name) -def _get_delimited_query_params(metadata: dict, field_name: str, obj: any, delimiter: str) -> dict[ - str, list[str]]: +def _get_delimited_query_params(metadata: Dict, field_name: str, obj: any, delimiter: str) -> Dict[ + str, List[str]]: return _populate_form(field_name, metadata.get("explode", True), obj, _get_query_param_field_name, delimiter) @@ -390,17 +394,22 @@ def _get_delimited_query_params(metadata: dict, field_name: str, obj: any, delim } -def serialize_request_body(request: dataclass, request_field_name: str, serialization_method: str) -> Tuple[ - str, any, any]: +def serialize_request_body(request: dataclass, request_field_name: str, nullable: bool, optional: bool, serialization_method: str, encoder=None) -> Tuple[ + str, any, any]: if request is None: - return None, None, None, None + if not nullable and optional: + return None, None, None if not is_dataclass(request) or not hasattr(request, request_field_name): return serialize_content_type(request_field_name, SERIALIZATION_METHOD_TO_CONTENT_TYPE[serialization_method], - request) + request, encoder) request_val = getattr(request, request_field_name) + if request_val is None: + if not nullable and optional: + return None, None, None + request_fields: Tuple[Field, ...] = fields(request) request_metadata = None @@ -416,9 +425,9 @@ def serialize_request_body(request: dataclass, request_field_name: str, serializ request_val) -def serialize_content_type(field_name: str, media_type: str, request: dataclass) -> Tuple[str, any, list[list[any]]]: +def serialize_content_type(field_name: str, media_type: str, request: dataclass, encoder=None) -> Tuple[str, any, List[List[any]]]: if re.match(r'(application|text)\/.*?\+*json.*', media_type) is not None: - return media_type, marshal_json(request), None + return media_type, marshal_json(request, encoder), None if re.match(r'multipart\/.*', media_type) is not None: return serialize_multipart_form(media_type, request) if re.match(r'application\/x-www-form-urlencoded.*', media_type) is not None: @@ -432,8 +441,8 @@ def serialize_content_type(field_name: str, media_type: str, request: dataclass) f"invalid request body type {type(request)} for mediaType {media_type}") -def serialize_multipart_form(media_type: str, request: dataclass) -> Tuple[str, any, list[list[any]]]: - form: list[list[any]] = [] +def serialize_multipart_form(media_type: str, request: dataclass) -> Tuple[str, any, List[List[any]]]: + form: List[List[any]] = [] request_fields = fields(request) for field in request_fields: @@ -474,7 +483,7 @@ def serialize_multipart_form(media_type: str, request: dataclass) -> Tuple[str, else: field_name = field_metadata.get( "field_name", field.name) - if isinstance(val, list): + if isinstance(val, List): for value in val: if value is None: continue @@ -485,8 +494,8 @@ def serialize_multipart_form(media_type: str, request: dataclass) -> Tuple[str, return media_type, None, form -def serialize_dict(original: dict, explode: bool, field_name, existing: Optional[dict[str, list[str]]]) -> dict[ - str, list[str]]: +def serialize_dict(original: Dict, explode: bool, field_name, existing: Optional[Dict[str, List[str]]]) -> Dict[ + str, List[str]]: if existing is None: existing = [] @@ -506,8 +515,8 @@ def serialize_dict(original: dict, explode: bool, field_name, existing: Optional return existing -def serialize_form_data(field_name: str, data: dataclass) -> dict[str, any]: - form: dict[str, list[str]] = {} +def serialize_form_data(field_name: str, data: dataclass) -> Dict[str, any]: + form: Dict[str, List[str]] = {} if is_dataclass(data): for field in fields(data): @@ -525,12 +534,12 @@ def serialize_form_data(field_name: str, data: dataclass) -> dict[str, any]: form[field_name] = [marshal_json(val)] else: if metadata.get('style', 'form') == 'form': - form = form | _populate_form( - field_name, metadata.get('explode', True), val, _get_form_field_name, ",") + form = {**form, **_populate_form( + field_name, metadata.get('explode', True), val, _get_form_field_name, ",")} else: raise Exception( f'Invalid form style for field {field.name}') - elif isinstance(data, dict): + elif isinstance(data, Dict): for key, value in data.items(): form[key] = [_val_to_string(value)] else: @@ -549,8 +558,8 @@ def _get_form_field_name(obj_field: Field) -> str: def _populate_form(field_name: str, explode: boolean, obj: any, get_field_name_func: Callable, delimiter: str) -> \ - dict[str, list[str]]: - params: dict[str, list[str]] = {} + Dict[str, List[str]]: + params: Dict[str, List[str]] = {} if obj is None: return params @@ -576,7 +585,7 @@ def _populate_form(field_name: str, explode: boolean, obj: any, get_field_name_f if len(items) > 0: params[field_name] = [delimiter.join(items)] - elif isinstance(obj, dict): + elif isinstance(obj, Dict): items = [] for key, value in obj.items(): if value is None: @@ -589,7 +598,7 @@ def _populate_form(field_name: str, explode: boolean, obj: any, get_field_name_f if len(items) > 0: params[field_name] = [delimiter.join(items)] - elif isinstance(obj, list): + elif isinstance(obj, List): items = [] for value in obj: @@ -604,7 +613,8 @@ def _populate_form(field_name: str, explode: boolean, obj: any, get_field_name_f items.append(_val_to_string(value)) if len(items) > 0: - params[field_name] = [delimiter.join([str(item) for item in items])] + params[field_name] = [delimiter.join( + [str(item) for item in items])] else: params[field_name] = [_val_to_string(obj)] @@ -642,7 +652,7 @@ def _serialize_header(explode: bool, obj: any) -> str: if len(items) > 0: return ','.join(items) - elif isinstance(obj, dict): + elif isinstance(obj, Dict): items = [] for key, value in obj.items(): @@ -657,7 +667,7 @@ def _serialize_header(explode: bool, obj: any) -> str: if len(items) > 0: return ','.join([str(item) for item in items]) - elif isinstance(obj, list): + elif isinstance(obj, List): items = [] for value in obj: @@ -674,23 +684,28 @@ def _serialize_header(explode: bool, obj: any) -> str: return '' -def unmarshal_json(data, typ): +def unmarshal_json(data, typ, decoder=None): unmarshal = make_dataclass('Unmarshal', [('res', typ)], bases=(DataClassJsonMixin,)) json_dict = json.loads(data) try: out = unmarshal.from_dict({"res": json_dict}) except AttributeError as attr_err: - raise AttributeError(f'unable to unmarshal {data} as {typ}') from attr_err - return out.res + raise AttributeError( + f'unable to unmarshal {data} as {typ}') from attr_err + + return out.res if decoder is None else decoder(out.res) -def marshal_json(val): +def marshal_json(val, encoder=None): marshal = make_dataclass('Marshal', [('res', type(val))], bases=(DataClassJsonMixin,)) marshaller = marshal(res=val) json_dict = marshaller.to_dict() - return json.dumps(json_dict["res"]) + + val = json_dict["res"] if encoder is None else encoder(json_dict["res"]) + + return json.dumps(val) def match_content_type(content_type: str, pattern: str) -> boolean: @@ -734,6 +749,86 @@ def datefromisoformat(date_str: str): return dateutil.parser.parse(date_str).date() +def bigintencoder(optional: bool): + def bigintencode(val: int): + if optional and val is None: + return None + return str(val) + + return bigintencode + + +def bigintdecoder(val): + return int(val) + + +def decimalencoder(optional: bool, as_str: bool): + def decimalencode(val: Decimal): + if optional and val is None: + return None + + if as_str: + return str(val) + + return float(val) + + return decimalencode + + +def decimaldecoder(val): + return Decimal(str(val)) + + +def map_encoder(optional: bool, value_encoder: Callable): + def map_encode(val: Dict): + if optional and val is None: + return None + + encoded = {} + for key, value in val.items(): + encoded[key] = value_encoder(value) + + return encoded + + return map_encode + + +def map_decoder(value_decoder: Callable): + def map_decode(val: Dict): + decoded = {} + for key, value in val.items(): + decoded[key] = value_decoder(value) + + return decoded + + return map_decode + + +def list_encoder(optional: bool, value_encoder: Callable): + def list_encode(val: List): + if optional and val is None: + return None + + encoded = [] + for value in val: + encoded.append(value_encoder(value)) + + return encoded + + return list_encode + + +def list_decoder(value_decoder: Callable): + def list_decode(val: List): + decoded = [] + for value in val: + decoded.append(value_decoder(value)) + + return decoded + + return list_decode + + def get_field_name(name): def override(_, _field_name=name): return _field_name @@ -752,7 +847,7 @@ def _val_to_string(val): return str(val) -def _populate_from_globals(param_name: str, value: any, param_type: str, gbls: dict[str, dict[str, dict[str, Any]]]): +def _populate_from_globals(param_name: str, value: any, param_type: str, gbls: Dict[str, Dict[str, Dict[str, Any]]]): if value is None and gbls is not None: if 'parameters' in gbls: if param_type in gbls['parameters']: @@ -762,3 +857,16 @@ def _populate_from_globals(param_name: str, value: any, param_type: str, gbls: d value = global_value return value + + +def decoder_with_discriminator(field_name): + def decode_fx(obj): + kls = getattr(sys.modules['sdk.models.shared'], obj[field_name]) + return unmarshal_json(json.dumps(obj), kls) + return decode_fx + + +def remove_suffix(input_string, suffix): + if suffix and input_string.endswith(suffix): + return input_string[:-len(suffix)] + return input_string