- Implement tests for basic and bearer authentication headers in `test_auth.py`. - Create tests for the `EasybillWebhookParser` in `test_webhooks.py`, covering JSON and form-encoded payloads, as well as a generic parse and acknowledgement method.
176 lines
9 KiB
Python
176 lines
9 KiB
Python
# coding: utf-8
|
|
|
|
"""
|
|
easybill REST API
|
|
|
|
The first version of the easybill REST API. [CHANGELOG](https://api.easybill.de/rest/v1/CHANGELOG.md) ## Authentication You can choose between two available methods: `Basic Auth` or `Bearer Token`. In each HTTP request, one of the following HTTP headers is required: ``` # Basic Auth Authorization: Basic base64_encode('<email>:<api_key>') # Bearer Token Authorization: Bearer <api_key> ``` ## Limitations ### Request Limit * PLUS: 10 requests per minute * BUSINESS: 60 requests per minute If the limit is exceeded, you will receive the HTTP error: `429 Too Many Requests` ### Result Limit All result lists are limited to 100 by default. This limit can be increased by the query parameter `limit` to a maximum of 1000. ## Query filter Many list resources can be filtered. In `/documents` you can filter e.g. by number with `/documents?number=111028654`. If you want to filter multiple numbers, you can either enter them separated by commas `/documents?number=111028654,222006895` or as an array `/documents?number[]=111028654&number[]=222006895`. **Warning**: The maximum size of an HTTP request line in bytes is 4094. If this limit is exceeded, you will receive the HTTP error: `414 Request-URI Too Large` ### Escape commas in query You can escape commans in query `name=Patrick\\, Peter` if you submit the header `X-Easybill-Escape: true` in your request. ## Property login_id This is the login of your admin or employee account. ## Date and Date-Time format Please use the timezone `Europe/Berlin`. * **date** = *Y-m-d* = `2016-12-31` * **date-time** = *Y-m-d H:i:s* = `2016-12-31 03:13:37` Date or datetime can be `null` because the attributes have been added later and the entry is older.
|
|
|
|
The version of the OpenAPI document: 1.96.0
|
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
|
|
Do not edit the class manually.
|
|
""" # noqa: E501
|
|
|
|
|
|
from __future__ import annotations
|
|
import pprint
|
|
import re # noqa: F401
|
|
import json
|
|
|
|
from datetime import date, datetime
|
|
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr, field_validator
|
|
from typing import Any, ClassVar, Dict, List, Optional
|
|
from typing import Optional, Set
|
|
from typing_extensions import Self
|
|
from pydantic_core import to_jsonable_python
|
|
|
|
class PostBox(BaseModel):
|
|
"""
|
|
PostBox
|
|
""" # noqa: E501
|
|
id: Optional[StrictInt] = None
|
|
document_id: Optional[StrictInt] = None
|
|
to: Optional[StrictStr] = None
|
|
cc: Optional[StrictStr] = None
|
|
var_from: Optional[StrictStr] = Field(default=None, alias="from")
|
|
subject: Optional[StrictStr] = None
|
|
message: Optional[StrictStr] = None
|
|
var_date: Optional[date] = Field(default=None, alias="date")
|
|
created_at: Optional[datetime] = None
|
|
processed_at: Optional[datetime] = None
|
|
send_by_self: Optional[StrictBool] = None
|
|
send_with_attachment: Optional[StrictBool] = None
|
|
type: Optional[StrictStr] = None
|
|
status: Optional[StrictStr] = None
|
|
status_msg: Optional[StrictStr] = None
|
|
login_id: Optional[StrictInt] = None
|
|
document_file_type: Optional[StrictStr] = None
|
|
post_send_type: Optional[StrictStr] = Field(default=None, description="This value indicates what method is used when the document is send via mail. The different types are offered by the german post as additional services. The registered mail options will include a tracking number which will be added to the postbox when known. If the value is omitted or empty when a postbox is created with the type \"POST\" post_send_type_standard will be used. For postbox with a different type than \"POST\" this field will hold a empty string. ")
|
|
tracking_identifier: Optional[StrictStr] = Field(default=None, description="If the document is send with one of the registered send types stated for post_send_type, a tracking identifier will be added to the postbox at a later point when the tracking identifier is provided by our service partner. ")
|
|
__properties: ClassVar[List[str]] = ["id", "document_id", "to", "cc", "from", "subject", "message", "date", "created_at", "processed_at", "send_by_self", "send_with_attachment", "type", "status", "status_msg", "login_id", "document_file_type", "post_send_type", "tracking_identifier"]
|
|
|
|
@field_validator('type')
|
|
def type_validate_enum(cls, value):
|
|
"""Validates the enum"""
|
|
if value is None:
|
|
return value
|
|
|
|
if value not in set(['FAX', 'EMAIL', 'POST']):
|
|
raise ValueError("must be one of enum values ('FAX', 'EMAIL', 'POST')")
|
|
return value
|
|
|
|
@field_validator('status')
|
|
def status_validate_enum(cls, value):
|
|
"""Validates the enum"""
|
|
if value is None:
|
|
return value
|
|
|
|
if value not in set(['WAITING', 'PREPARE', 'ERROR', 'OK', 'PROCESSING']):
|
|
raise ValueError("must be one of enum values ('WAITING', 'PREPARE', 'ERROR', 'OK', 'PROCESSING')")
|
|
return value
|
|
|
|
@field_validator('document_file_type')
|
|
def document_file_type_validate_enum(cls, value):
|
|
"""Validates the enum"""
|
|
if value is None:
|
|
return value
|
|
|
|
if value not in set(['default', 'zugferd1', 'zugferd2_2', 'zugferd2_4_en16931', 'zugferd2_4_extended', 'xrechnung', 'xrechnung_xml']):
|
|
raise ValueError("must be one of enum values ('default', 'zugferd1', 'zugferd2_2', 'zugferd2_4_en16931', 'zugferd2_4_extended', 'xrechnung', 'xrechnung_xml')")
|
|
return value
|
|
|
|
@field_validator('post_send_type')
|
|
def post_send_type_validate_enum(cls, value):
|
|
"""Validates the enum"""
|
|
if value is None:
|
|
return value
|
|
|
|
if value not in set(['post_send_type_standard', 'post_send_type_registered', 'post_send_type_registered_and_personal', 'post_send_type_registered_and_receipt', 'post_send_type_registered_throwin', 'post_send_type_prio']):
|
|
raise ValueError("must be one of enum values ('post_send_type_standard', 'post_send_type_registered', 'post_send_type_registered_and_personal', 'post_send_type_registered_and_receipt', 'post_send_type_registered_throwin', 'post_send_type_prio')")
|
|
return value
|
|
|
|
model_config = ConfigDict(
|
|
validate_by_name=True,
|
|
validate_by_alias=True,
|
|
validate_assignment=True,
|
|
protected_namespaces=(),
|
|
)
|
|
|
|
|
|
def to_str(self) -> str:
|
|
"""Returns the string representation of the model using alias"""
|
|
return pprint.pformat(self.model_dump(by_alias=True))
|
|
|
|
def to_json(self) -> str:
|
|
"""Returns the JSON representation of the model using alias"""
|
|
return json.dumps(to_jsonable_python(self.to_dict()))
|
|
|
|
@classmethod
|
|
def from_json(cls, json_str: str) -> Optional[Self]:
|
|
"""Create an instance of PostBox from a JSON string"""
|
|
return cls.from_dict(json.loads(json_str))
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""Return the dictionary representation of the model using alias.
|
|
|
|
This has the following differences from calling pydantic's
|
|
`self.model_dump(by_alias=True)`:
|
|
|
|
* `None` is only added to the output dict for nullable fields that
|
|
were set at model initialization. Other fields with value `None`
|
|
are ignored.
|
|
* OpenAPI `readOnly` fields are excluded.
|
|
* OpenAPI `readOnly` fields are excluded.
|
|
* OpenAPI `readOnly` fields are excluded.
|
|
"""
|
|
excluded_fields: Set[str] = set([
|
|
"id",
|
|
"login_id",
|
|
"tracking_identifier",
|
|
])
|
|
|
|
_dict = self.model_dump(
|
|
by_alias=True,
|
|
exclude=excluded_fields,
|
|
exclude_none=True,
|
|
)
|
|
# set to None if document_file_type (nullable) is None
|
|
# and model_fields_set contains the field
|
|
if self.document_file_type is None and "document_file_type" in self.model_fields_set:
|
|
_dict['document_file_type'] = None
|
|
|
|
return _dict
|
|
|
|
@classmethod
|
|
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
|
"""Create an instance of PostBox from a dict"""
|
|
if obj is None:
|
|
return None
|
|
|
|
if not isinstance(obj, dict):
|
|
return cls.model_validate(obj)
|
|
|
|
_obj = cls.model_validate({
|
|
"id": obj.get("id"),
|
|
"document_id": obj.get("document_id"),
|
|
"to": obj.get("to"),
|
|
"cc": obj.get("cc"),
|
|
"from": obj.get("from"),
|
|
"subject": obj.get("subject"),
|
|
"message": obj.get("message"),
|
|
"date": obj.get("date"),
|
|
"created_at": obj.get("created_at"),
|
|
"processed_at": obj.get("processed_at"),
|
|
"send_by_self": obj.get("send_by_self"),
|
|
"send_with_attachment": obj.get("send_with_attachment"),
|
|
"type": obj.get("type"),
|
|
"status": obj.get("status"),
|
|
"status_msg": obj.get("status_msg"),
|
|
"login_id": obj.get("login_id"),
|
|
"document_file_type": obj.get("document_file_type"),
|
|
"post_send_type": obj.get("post_send_type"),
|
|
"tracking_identifier": obj.get("tracking_identifier")
|
|
})
|
|
return _obj
|
|
|
|
|