etld 0.1.2__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.
etld-0.1.2/PKG-INFO ADDED
@@ -0,0 +1,44 @@
1
+ Metadata-Version: 2.1
2
+ Name: etld
3
+ Version: 0.1.2
4
+ Summary: Official Python SDK for the ETL-D API - Stateless Data Middleware for AI Agents.
5
+ Home-page: https://github.com/pablixnieto2/enrichermagic
6
+ Author: ETL-D Team
7
+ Author-email: hello@etl-d.net
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.7
12
+ Description-Content-Type: text/markdown
13
+
14
+ # ETL-D Python SDK
15
+
16
+ Limpia, normaliza y estructura datos globales (direcciones, nombres, importes) con nuestro motor de IA asíncrono.
17
+
18
+ ## ¿Cómo funciona nuestra arquitectura asíncrona?
19
+
20
+ A diferencia de otras APIs que te bloquean el hilo esperando una respuesta, ETL-D utiliza un sistema de colas (Celery/Redis).
21
+ 1. **Envío:** Tú envías un lote de miles de registros.
22
+ 2. **Procesamiento:** El sistema te devuelve un `task_id` instantáneo.
23
+ 3. **Polling automático:** Nuestro SDK se queda consultando el estado por ti (en segundo plano) hasta que el trabajo termina, devolviéndote los datos limpios directamente.
24
+
25
+ ## Ejemplo de uso (El cliente se encarga del robot por ti)
26
+
27
+ ```python
28
+ from etld import ETLDClient
29
+
30
+ client = ETLDClient(api_key="TU_API_KEY")
31
+
32
+ # Esta función envía los datos y se queda esperando (polling)
33
+ # hasta que el servidor dice "SUCCESS".
34
+ datos_limpios = client.batch_process(
35
+ items=[
36
+ "Calle 70A No. 11 - 12, Bogotá",
37
+ "152 Teheran-ro, Seoul"
38
+ ],
39
+ entity_type="address"
40
+ )
41
+
42
+ for resultado in datos_limpios:
43
+ print(resultado['address_latin'])
44
+ ```
etld-0.1.2/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # ETL-D Python SDK
2
+
3
+ Limpia, normaliza y estructura datos globales (direcciones, nombres, importes) con nuestro motor de IA asíncrono.
4
+
5
+ ## ¿Cómo funciona nuestra arquitectura asíncrona?
6
+
7
+ A diferencia de otras APIs que te bloquean el hilo esperando una respuesta, ETL-D utiliza un sistema de colas (Celery/Redis).
8
+ 1. **Envío:** Tú envías un lote de miles de registros.
9
+ 2. **Procesamiento:** El sistema te devuelve un `task_id` instantáneo.
10
+ 3. **Polling automático:** Nuestro SDK se queda consultando el estado por ti (en segundo plano) hasta que el trabajo termina, devolviéndote los datos limpios directamente.
11
+
12
+ ## Ejemplo de uso (El cliente se encarga del robot por ti)
13
+
14
+ ```python
15
+ from etld import ETLDClient
16
+
17
+ client = ETLDClient(api_key="TU_API_KEY")
18
+
19
+ # Esta función envía los datos y se queda esperando (polling)
20
+ # hasta que el servidor dice "SUCCESS".
21
+ datos_limpios = client.batch_process(
22
+ items=[
23
+ "Calle 70A No. 11 - 12, Bogotá",
24
+ "152 Teheran-ro, Seoul"
25
+ ],
26
+ entity_type="address"
27
+ )
28
+
29
+ for resultado in datos_limpios:
30
+ print(resultado['address_latin'])
31
+ ```
@@ -0,0 +1,22 @@
1
+ from .client import ETLDClient
2
+ from .models import ContextParams, AddressOutput, NameOutput, MoneyOutput
3
+ from .exceptions import (
4
+ ETLDBaseException,
5
+ ETLDAuthenticationError,
6
+ ETLDRateLimitError,
7
+ ETLDProcessingError,
8
+ ETLDValidationError
9
+ )
10
+
11
+ __all__ = [
12
+ "ETLDClient",
13
+ "ContextParams",
14
+ "AddressOutput",
15
+ "NameOutput",
16
+ "MoneyOutput",
17
+ "ETLDBaseException",
18
+ "ETLDAuthenticationError",
19
+ "ETLDRateLimitError",
20
+ "ETLDProcessingError",
21
+ "ETLDValidationError",
22
+ ]
@@ -0,0 +1,112 @@
1
+ import requests
2
+ import time
3
+ from typing import List, Optional, Dict, Any, Union
4
+ from .models import ContextParams, AddressOutput, NameOutput, MoneyOutput
5
+ from .exceptions import (
6
+ ETLDAuthenticationError,
7
+ ETLDRateLimitError,
8
+ ETLDProcessingError,
9
+ ETLDValidationError
10
+ )
11
+
12
+ class ETLDClient:
13
+ def __init__(self, api_key: str, base_url: str = "https://api.etl-d.net"):
14
+ self.api_key = api_key
15
+ self.base_url = base_url.rstrip("/")
16
+ self.session = requests.Session()
17
+ self.session.headers.update({
18
+ "X-API-KEY": self.api_key,
19
+ "Content-Type": "application/json",
20
+ "User-Agent": "etld-python-sdk/0.1.0"
21
+ })
22
+
23
+ def _handle_response(self, response: requests.Response) -> Dict[str, Any]:
24
+ if response.status_code == 401 or response.status_code == 403:
25
+ raise ETLDAuthenticationError(f"Invalid API Key: {response.text}")
26
+ elif response.status_code == 429:
27
+ raise ETLDRateLimitError(f"Rate limit exceeded: {response.text}")
28
+ elif response.status_code == 422:
29
+ raise ETLDValidationError(f"Validation Error: {response.json().get('detail')}")
30
+
31
+ try:
32
+ response.raise_for_status()
33
+ except requests.exceptions.HTTPError as e:
34
+ raise ETLDProcessingError(f"API Request failed: {str(e)}")
35
+
36
+ return response.json()
37
+
38
+ def enrich_address(self, address: str, context: Optional[Union[Dict[str, Any], ContextParams]] = None) -> AddressOutput:
39
+ if isinstance(context, ContextParams):
40
+ context = context.to_dict()
41
+
42
+ payload = {
43
+ "address_line": address,
44
+ "context": context or {}
45
+ }
46
+
47
+ data = self._handle_response(self.session.post(f"{self.base_url}/v1/enrich/address", json=payload))
48
+ return AddressOutput(**data)
49
+
50
+ def enrich_name(self, name: str, context: Optional[Union[Dict[str, Any], ContextParams]] = None) -> NameOutput:
51
+ if isinstance(context, ContextParams):
52
+ context = context.to_dict()
53
+
54
+ payload = {
55
+ "full_name": name,
56
+ "context": context or {}
57
+ }
58
+
59
+ data = self._handle_response(self.session.post(f"{self.base_url}/v1/enrich/name", json=payload))
60
+ return NameOutput(**data)
61
+
62
+ def enrich_amount(self, amount: str, context: Optional[Union[Dict[str, Any], ContextParams]] = None) -> MoneyOutput:
63
+ if isinstance(context, ContextParams):
64
+ context = context.to_dict()
65
+
66
+ payload = {
67
+ "amount_string": amount,
68
+ "context": context or {}
69
+ }
70
+
71
+ data = self._handle_response(self.session.post(f"{self.base_url}/v1/enrich/amount", json=payload))
72
+ return MoneyOutput(**data)
73
+
74
+ def batch_process(
75
+ self,
76
+ items: List[str],
77
+ entity_type: str,
78
+ context: Optional[Union[Dict[str, Any], ContextParams]] = None,
79
+ poll_interval: int = 2,
80
+ max_retries: int = 30
81
+ ) -> List[Any]:
82
+ if isinstance(context, ContextParams):
83
+ context = context.to_dict()
84
+
85
+ payload = {
86
+ "items": items,
87
+ "context": context or {}
88
+ }
89
+
90
+ # 1. Start Batch
91
+ start_data = self._handle_response(
92
+ self.session.post(f"{self.base_url}/v1/enrich/batch/{entity_type}", json=payload)
93
+ )
94
+ task_id = start_data.get("task_id")
95
+
96
+ # 2. Poll
97
+ retries = 0
98
+ while retries < max_retries:
99
+ status_data = self._handle_response(
100
+ self.session.get(f"{self.base_url}/v1/enrich/batch/{task_id}")
101
+ )
102
+
103
+ status = status_data.get("status")
104
+ if status == "SUCCESS":
105
+ return status_data.get("results", [])
106
+ elif status == "FAILURE":
107
+ raise ETLDProcessingError(f"Batch processing failed: {status_data.get('error')}")
108
+
109
+ time.sleep(poll_interval)
110
+ retries += 1
111
+
112
+ raise ETLDProcessingError(f"Batch processing timed out for task {task_id}")
@@ -0,0 +1,19 @@
1
+ class ETLDBaseException(Exception):
2
+ """Base exception for ETL-D SDK"""
3
+ pass
4
+
5
+ class ETLDAuthenticationError(ETLDBaseException):
6
+ """Raised when API key is invalid or missing"""
7
+ pass
8
+
9
+ class ETLDRateLimitError(ETLDBaseException):
10
+ """Raised when API rate limit is exceeded"""
11
+ pass
12
+
13
+ class ETLDProcessingError(ETLDBaseException):
14
+ """Raised when there is an error processing the request"""
15
+ pass
16
+
17
+ class ETLDValidationError(ETLDBaseException):
18
+ """Raised when request validation fails"""
19
+ pass
@@ -0,0 +1,53 @@
1
+ from dataclasses import dataclass, field
2
+ from typing import Optional, List, Any, Dict
3
+
4
+ @dataclass
5
+ class ContextParams:
6
+ timezone: str = "UTC"
7
+ locale: str = "en_US"
8
+ target_currency: Optional[str] = None
9
+ transliterate: bool = False
10
+
11
+ def to_dict(self) -> Dict[str, Any]:
12
+ return {k: v for k, v in self.__dict__.items() if v is not None}
13
+
14
+ @dataclass
15
+ class AddressOutput:
16
+ street: Optional[str] = None
17
+ house_number: Optional[str] = None
18
+ floor_unit: Optional[str] = None
19
+ postal_code: Optional[str] = None
20
+ city: Optional[str] = None
21
+ state: Optional[str] = None
22
+ country: Optional[str] = None
23
+ type: Optional[str] = None
24
+ address_latin: Optional[str] = None
25
+ error: Optional[str] = None
26
+
27
+ @dataclass
28
+ class NameOutput:
29
+ title: Optional[str] = None
30
+ first: Optional[str] = None
31
+ middle: Optional[str] = None
32
+ last: Optional[str] = None
33
+ suffix: Optional[str] = None
34
+ nickname: Optional[str] = None
35
+ gender: Optional[str] = None
36
+ confidence: Optional[str] = None
37
+ name_latin: Optional[str] = None
38
+
39
+ @dataclass
40
+ class MoneyOutput:
41
+ float_value: Optional[float] = None
42
+ currency: Optional[str] = None
43
+ currency_symbol: Optional[str] = None
44
+ clean_string: Optional[str] = None
45
+ conversion_required: Optional[bool] = None
46
+ error: Optional[str] = None
47
+
48
+ @dataclass
49
+ class BatchResponse:
50
+ task_id: str
51
+ status: str
52
+ results: Optional[List[Any]] = None
53
+ error: Optional[str] = None
@@ -0,0 +1,44 @@
1
+ Metadata-Version: 2.1
2
+ Name: etld
3
+ Version: 0.1.2
4
+ Summary: Official Python SDK for the ETL-D API - Stateless Data Middleware for AI Agents.
5
+ Home-page: https://github.com/pablixnieto2/enrichermagic
6
+ Author: ETL-D Team
7
+ Author-email: hello@etl-d.net
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.7
12
+ Description-Content-Type: text/markdown
13
+
14
+ # ETL-D Python SDK
15
+
16
+ Limpia, normaliza y estructura datos globales (direcciones, nombres, importes) con nuestro motor de IA asíncrono.
17
+
18
+ ## ¿Cómo funciona nuestra arquitectura asíncrona?
19
+
20
+ A diferencia de otras APIs que te bloquean el hilo esperando una respuesta, ETL-D utiliza un sistema de colas (Celery/Redis).
21
+ 1. **Envío:** Tú envías un lote de miles de registros.
22
+ 2. **Procesamiento:** El sistema te devuelve un `task_id` instantáneo.
23
+ 3. **Polling automático:** Nuestro SDK se queda consultando el estado por ti (en segundo plano) hasta que el trabajo termina, devolviéndote los datos limpios directamente.
24
+
25
+ ## Ejemplo de uso (El cliente se encarga del robot por ti)
26
+
27
+ ```python
28
+ from etld import ETLDClient
29
+
30
+ client = ETLDClient(api_key="TU_API_KEY")
31
+
32
+ # Esta función envía los datos y se queda esperando (polling)
33
+ # hasta que el servidor dice "SUCCESS".
34
+ datos_limpios = client.batch_process(
35
+ items=[
36
+ "Calle 70A No. 11 - 12, Bogotá",
37
+ "152 Teheran-ro, Seoul"
38
+ ],
39
+ entity_type="address"
40
+ )
41
+
42
+ for resultado in datos_limpios:
43
+ print(resultado['address_latin'])
44
+ ```
@@ -0,0 +1,11 @@
1
+ README.md
2
+ setup.py
3
+ etld/__init__.py
4
+ etld/client.py
5
+ etld/exceptions.py
6
+ etld/models.py
7
+ etld.egg-info/PKG-INFO
8
+ etld.egg-info/SOURCES.txt
9
+ etld.egg-info/dependency_links.txt
10
+ etld.egg-info/requires.txt
11
+ etld.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ requests>=2.25.0
@@ -0,0 +1 @@
1
+ etld
etld-0.1.2/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
etld-0.1.2/setup.py ADDED
@@ -0,0 +1,22 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="etld",
5
+ version="0.1.2",
6
+ author="ETL-D Team",
7
+ author_email="hello@etl-d.net",
8
+ description="Official Python SDK for the ETL-D API - Stateless Data Middleware for AI Agents.",
9
+ long_description=open("README.md").read(),
10
+ long_description_content_type="text/markdown",
11
+ url="https://github.com/pablixnieto2/enrichermagic",
12
+ packages=find_packages(),
13
+ install_requires=[
14
+ "requests>=2.25.0",
15
+ ],
16
+ classifiers=[
17
+ "Programming Language :: Python :: 3",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Operating System :: OS Independent",
20
+ ],
21
+ python_requires='>=3.7',
22
+ )