stackin-python-sdk 0.1.0__tar.gz → 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stackin-python-sdk
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Python SDK for issuing, consulting and cancelling electronic invoices.
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -20,6 +20,11 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
20
  Classifier: Natural Language :: Portuguese (Brazilian)
21
21
  Requires-Dist: pydantic
22
22
  Requires-Dist: requests
23
+ Project-URL: Changelog, https://github.com/stackin-io/stackin-python-sdk/releases
24
+ Project-URL: Documentation, https://docs.stackin.io/blog/python-sdk
25
+ Project-URL: Homepage, https://docs.stackin.io
26
+ Project-URL: Issues, https://github.com/stackin-io/stackin-python-sdk/issues
27
+ Project-URL: Repository, https://github.com/stackin-io/stackin-python-sdk
23
28
  Description-Content-Type: text/markdown
24
29
 
25
30
  <div align="center">
@@ -29,8 +34,11 @@ Description-Content-Type: text/markdown
29
34
  **Integrate once. Issue everywhere.**
30
35
 
31
36
  [![Python](https://img.shields.io/badge/python-3.10%2B-blue?style=flat-square)](pyproject.toml)
37
+ [![PyPI](https://img.shields.io/pypi/v/stackin-python-sdk?style=flat-square)](https://pypi.org/project/stackin-python-sdk/)
32
38
  [![License](https://img.shields.io/badge/license-MIT-informational?style=flat-square)](https://github.com/stackin-io/stackin-python-sdk)
33
39
 
40
+ [API Reference](https://docs.stackin.io) · [Python SDK guide](https://docs.stackin.io/blog/python-sdk)
41
+
34
42
  </div>
35
43
 
36
44
  ---
@@ -49,7 +57,7 @@ pip install stackin-python-sdk
49
57
 
50
58
  ## Usage
51
59
 
52
- Get an `api_key` from the [stackin dashboard](https://app.stackin.io) — select the issuing company, then Settings → API key. One key per issuing company, shown once at creation. The API resolves the issuer (CNPJ, state, address, certificate, environment) entirely from it; nothing about the issuer is ever passed on a call.
60
+ Get an `api_key` from the [stackin dashboard](https://app.stackin.io) — select the issuing company, then Settings → API key (context `sdk`). One key per issuing company, shown once at creation. The API resolves the issuer (CNPJ, state, address, certificate, environment) entirely from it; nothing about the issuer is ever passed on a call.
53
61
 
54
62
  ```python
55
63
  from stackin import Invoice, DocumentType, Address
@@ -98,17 +106,3 @@ Building the full fiscal document (issuer data, service code, tax groups, schema
98
106
 
99
107
  Runnable end-to-end scripts in [`examples/`](examples/) — `simple_issue_nfe.py` and `simple_issue_nfse.py`, each with a catalog of realistic line items covering every optional field.
100
108
 
101
- ## Commit Style
102
-
103
- | Icon | Type | Description |
104
- |------|-----------|--------------------------------------------|
105
- | ⚙️ | FEATURE | New feature |
106
- | 📝 | PEP8 | Formatting fixes following PEP8 |
107
- | 📌 | ISSUE | Reference to issue |
108
- | 🪲 | BUG | Bug fix |
109
- | 📘 | DOCS | Documentation changes |
110
- | 📦 | PyPI | PyPI releases |
111
- | ❤️️ | TEST | Automated tests |
112
- | ⬆️ | CI/CD | Changes in continuous integration/delivery |
113
- | ⚠️ | SECURITY | Security improvements |
114
-
@@ -5,8 +5,11 @@
5
5
  **Integrate once. Issue everywhere.**
6
6
 
7
7
  [![Python](https://img.shields.io/badge/python-3.10%2B-blue?style=flat-square)](pyproject.toml)
8
+ [![PyPI](https://img.shields.io/pypi/v/stackin-python-sdk?style=flat-square)](https://pypi.org/project/stackin-python-sdk/)
8
9
  [![License](https://img.shields.io/badge/license-MIT-informational?style=flat-square)](https://github.com/stackin-io/stackin-python-sdk)
9
10
 
11
+ [API Reference](https://docs.stackin.io) · [Python SDK guide](https://docs.stackin.io/blog/python-sdk)
12
+
10
13
  </div>
11
14
 
12
15
  ---
@@ -25,7 +28,7 @@ pip install stackin-python-sdk
25
28
 
26
29
  ## Usage
27
30
 
28
- Get an `api_key` from the [stackin dashboard](https://app.stackin.io) — select the issuing company, then Settings → API key. One key per issuing company, shown once at creation. The API resolves the issuer (CNPJ, state, address, certificate, environment) entirely from it; nothing about the issuer is ever passed on a call.
31
+ Get an `api_key` from the [stackin dashboard](https://app.stackin.io) — select the issuing company, then Settings → API key (context `sdk`). One key per issuing company, shown once at creation. The API resolves the issuer (CNPJ, state, address, certificate, environment) entirely from it; nothing about the issuer is ever passed on a call.
29
32
 
30
33
  ```python
31
34
  from stackin import Invoice, DocumentType, Address
@@ -73,17 +76,3 @@ Building the full fiscal document (issuer data, service code, tax groups, schema
73
76
  ## Examples
74
77
 
75
78
  Runnable end-to-end scripts in [`examples/`](examples/) — `simple_issue_nfe.py` and `simple_issue_nfse.py`, each with a catalog of realistic line items covering every optional field.
76
-
77
- ## Commit Style
78
-
79
- | Icon | Type | Description |
80
- |------|-----------|--------------------------------------------|
81
- | ⚙️ | FEATURE | New feature |
82
- | 📝 | PEP8 | Formatting fixes following PEP8 |
83
- | 📌 | ISSUE | Reference to issue |
84
- | 🪲 | BUG | Bug fix |
85
- | 📘 | DOCS | Documentation changes |
86
- | 📦 | PyPI | PyPI releases |
87
- | ❤️️ | TEST | Automated tests |
88
- | ⬆️ | CI/CD | Changes in continuous integration/delivery |
89
- | ⚠️ | SECURITY | Security improvements |
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "stackin-python-sdk"
3
- version = "0.1.0"
3
+ version = "0.1.1"
4
4
  authors = [
5
5
  { name = "Fernando Celmer", email = "email@fernandocelmer.com" },
6
6
  ]
@@ -36,9 +36,16 @@ dependencies = [
36
36
  "pydantic",
37
37
  ]
38
38
 
39
+ [project.urls]
40
+ Homepage = "https://docs.stackin.io"
41
+ Documentation = "https://docs.stackin.io/blog/python-sdk"
42
+ Repository = "https://github.com/stackin-io/stackin-python-sdk"
43
+ Issues = "https://github.com/stackin-io/stackin-python-sdk/issues"
44
+ Changelog = "https://github.com/stackin-io/stackin-python-sdk/releases"
45
+
39
46
  [tool.poetry]
40
47
  name = "stackin-python-sdk"
41
- version = "0.1.0"
48
+ version = "0.1.1"
42
49
  description = "Python SDK for issuing, consulting and cancelling electronic invoices."
43
50
  authors = ["Fernando Celmer <email@fernandocelmer.com>"]
44
51
  readme = "README.md"
@@ -1,6 +1,6 @@
1
1
  """Invoice __init__ module."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.1.1"
4
4
  __description__ = (
5
5
  "Python SDK for issuing, consulting and cancelling electronic invoices."
6
6
  )
@@ -55,11 +55,13 @@ class Product(BaseModel):
55
55
  ncm: str | None = Field(default=None, pattern=r"^\d{2}$|^\d{8}$")
56
56
  cfop: str | None = Field(default=None, pattern=r"^[123567]\d{3}$")
57
57
  cest: str | None = Field(default=None, pattern=r"^\d{7}$")
58
- nve_codes: list[Annotated[str, Field(pattern=r"^[A-Z]{2}\d{4}$")]] | None = Field(
59
- default=None
60
- )
58
+ nve_codes: (
59
+ list[Annotated[str, Field(pattern=r"^[A-Z]{2}\d{4}$")]] | None
60
+ ) = Field(default=None)
61
61
  ind_escala: str | None = Field(default=None)
62
- manufacturer_cnpj: str | None = Field(default=None, pattern=r"^[0-9A-Z]{12}\d{2}$")
62
+ manufacturer_cnpj: str | None = Field(
63
+ default=None, pattern=r"^[0-9A-Z]{12}\d{2}$"
64
+ )
63
65
  tax_benefit_code: str | None = Field(default=None, pattern=_CBENEF_PATTERN)
64
66
  presumed_credits: list[PresumedCredit] | None = Field(default=None)
65
67
  ex_tipi: str | None = Field(default=None, pattern=r"^\d{2,3}$")
@@ -84,4 +86,8 @@ class Product(BaseModel):
84
86
  br["tax"] = self.tax
85
87
  if br:
86
88
  data["br"] = br
87
- return {"description": self.description, "amount": self.amount, "product": data}
89
+ return {
90
+ "description": self.description,
91
+ "amount": self.amount,
92
+ "product": data,
93
+ }
@@ -44,7 +44,9 @@ class Icms60(BaseModel):
44
44
  cst: str = Field(default="60", alias="CST")
45
45
  v_bc_st_ret: str | None = Field(default=None, alias="vBCSTRet")
46
46
  p_st: str | None = Field(default=None, alias="pST")
47
- v_icms_substituto: str | None = Field(default=None, alias="vICMSSubstituto")
47
+ v_icms_substituto: str | None = Field(
48
+ default=None, alias="vICMSSubstituto"
49
+ )
48
50
  v_icms_st_ret: str | None = Field(default=None, alias="vICMSSTRet")
49
51
  v_bc_fcp_st_ret: str | None = Field(default=None, alias="vBCFCPSTRet")
50
52
  p_fcp_st_ret: str | None = Field(default=None, alias="pFCPSTRet")
@@ -234,7 +236,9 @@ class Tax(BaseModel):
234
236
  by_alias=True, exclude_none=True
235
237
  )
236
238
  if self.ipi is not None:
237
- data["IPI"] = self.ipi.to_dict() if isinstance(self.ipi, Ipi) else self.ipi
239
+ data["IPI"] = (
240
+ self.ipi.to_dict() if isinstance(self.ipi, Ipi) else self.ipi
241
+ )
238
242
  if self.pis is not None:
239
243
  data["PIS"] = _wrap(self.pis, _PIS_TAGS)
240
244
  if self.cofins is not None:
@@ -246,4 +250,6 @@ def _wrap(group: BaseModel | dict, tags: dict[type, str]) -> dict:
246
250
  """Nests a tax group under its variant name."""
247
251
  if isinstance(group, dict):
248
252
  return group
249
- return {tags[type(group)]: group.model_dump(by_alias=True, exclude_none=True)}
253
+ return {
254
+ tags[type(group)]: group.model_dump(by_alias=True, exclude_none=True)
255
+ }
@@ -6,8 +6,8 @@ import os
6
6
 
7
7
  import requests
8
8
 
9
- from stackin.core.address import Address
10
9
  from stackin.br.product import Product
10
+ from stackin.core.address import Address
11
11
  from stackin.core.exceptions import APIError, ConnectionFailedError
12
12
  from stackin.core.types import DocumentType, Environment
13
13
 
@@ -71,7 +71,9 @@ class Invoice:
71
71
  if not item.ncm:
72
72
  raise ValueError(f"items[{index}].ncm is required for NFE")
73
73
  if not item.cfop:
74
- raise ValueError(f"items[{index}].cfop is required for NFE")
74
+ raise ValueError(
75
+ f"items[{index}].cfop is required for NFE"
76
+ )
75
77
 
76
78
  payload = {
77
79
  "document_type": document_type.value,
@@ -108,7 +110,9 @@ class Invoice:
108
110
  "reason": reason,
109
111
  }
110
112
 
111
- return self._request("POST", f"/invoices/{access_key}/cancel", json=payload)
113
+ return self._request(
114
+ "POST", f"/invoices/{access_key}/cancel", json=payload
115
+ )
112
116
 
113
117
  def _headers(self) -> dict:
114
118
  if self.api_key: