Python Client Example
Acest exemplu arată un wrapper Python simplu pentru API-ul SOAP Imopedia, folosind zeep și requests.
Codul este educațional: păstrează partea de sesiune într-o clasă mică, ascunde session_id și folosește un context manager ca să apeleze logout() la final.
Instalare
pip install zeep requests
Wrapper ImopediaClient
import base64
import requests
from zeep import Client
from zeep.exceptions import Fault
from zeep.transports import Transport
WSDL_URL = "https://www.imopedia.ro/soap.wsdl"
USERNAME = "USERNAME"
PASSWORD = "PASSWORD"
class ImopediaClient:
def __init__(self, wsdl_url, username, password, timeout=20):
self.username = username
self.password = password
self.session_id = None
http_session = requests.Session()
transport = Transport(
session=http_session,
timeout=timeout,
operation_timeout=timeout,
)
self.client = Client(wsdl=wsdl_url, transport=transport)
def __enter__(self):
self.login()
return self
def __exit__(self, exc_type, exc_value, traceback):
self.logout()
def login(self):
try:
self.session_id = self.client.service.login(
username=self.username,
password=self.password,
)
return self.session_id
except Fault as error:
raise RuntimeError(f"Login SOAP error: {error}") from error
def logout(self):
if not self.session_id:
return
try:
self.client.service.logout(session_id=self.session_id)
except Fault as error:
raise RuntimeError(f"Logout SOAP error: {error}") from error
finally:
self.session_id = None
def save_property(self, payload):
self._require_session()
try:
return self.client.service.saveProperty(
session_id=self.session_id,
options=payload,
)
except Fault as error:
raise RuntimeError(f"saveProperty SOAP error: {error}") from error
def save_agent(self, payload):
self._require_session()
try:
return self.client.service.saveAgent(
session_id=self.session_id,
options=payload,
)
except Fault as error:
raise RuntimeError(f"saveAgent SOAP error: {error}") from error
def add_file(
self,
agency_id,
local_id,
file_id,
file_title,
file_bytes,
file_url=None,
order=None,
):
self._require_session()
encoded_file = base64.b64encode(file_bytes).decode("ascii")
options = {
"AGENTIA": agency_id,
"ID_LOCAL": local_id,
"FILE_ID": file_id,
"FILE_TITLE": file_title,
"FILE_BODY": encoded_file,
}
if file_url is not None:
options["FILE_URL"] = file_url
if order is not None:
options["ORDER"] = order
try:
return self.client.service.addFile(
session_id=self.session_id,
options=options,
)
except Fault as error:
raise RuntimeError(f"addFile SOAP error: {error}") from error
def _require_session(self):
if not self.session_id:
raise RuntimeError("Clientul nu este autentificat. Apelează login() înainte de operații.")
def login_logout_example():
client = ImopediaClient(WSDL_URL, USERNAME, PASSWORD)
client.login()
try:
print("Sesiune deschisă.")
finally:
client.logout()
def is_valid_response(response):
return isinstance(response, dict) and response.get("_isValid") == "true"
if __name__ == "__main__":
agency_id = 123
agent_id = 45
property_payload = {
"AGENTIA": agency_id,
"ID_LOCAL": 67654,
"AGENT_ID": agent_id,
"IMOPEDIA": 1,
"TIP_IMOBIL_REAL": 1,
"DATA_APARITIE": "2026-05-28",
"DATA_MODIFICARE": "2026-05-28",
"TITLU": "Apartament 2 camere - exemplu",
"T_V_TRANZ": 1,
"T_V_PRET": 120000,
"T_V_MONEDA": "EUR",
"JUDET": "Bucuresti",
"JUDET_ID": 10,
"ORAS": "Bucuresti",
"ZONA": "Central",
"SUPR_UTILA": 58,
"NRCAM": 2,
"CONTACT_PERS": "Agent Exemplu",
"CONTACT_EMAIL": "agent@example.com",
"CONTACT_TEL": "+40 700 000 000",
}
with ImopediaClient(WSDL_URL, USERNAME, PASSWORD, timeout=30) as api:
agent_result = api.save_agent(
{
"AGENTIA": agency_id,
"AGENT_ID": agent_id,
"CONTACT_PERS": "Agent Exemplu",
"CONTACT_EMAIL": "agent@example.com",
"CONTACT_TEL": "+40 700 000 000",
}
)
print(agent_result)
property_result = api.save_property(property_payload)
print(property_result)
if not is_valid_response(property_result):
raise RuntimeError("Oferta nu a fost acceptată; nu continua cu fișiere media.")
# Persistă ID_LOCAL numeric. Dacă API-ul a alocat unul, folosește-l
# pentru media, actualizări, ștergere, promovare și URL public.
success_items = property_result.get("_success", [])
if isinstance(success_items, dict):
first_success = success_items.get("0") or success_items.get(0) or {}
elif success_items:
first_success = success_items[0]
else:
first_success = {}
result_data = first_success.get("result", {})
local_id = result_data.get("ID_LOCAL", property_payload.get("ID_LOCAL"))
image_bytes = b"EXAMPLE FILE CONTENT"
file_result = api.add_file(
agency_id=agency_id,
local_id=local_id,
file_id="photo-01",
file_title="Fotografie exemplu",
file_bytes=image_bytes,
file_url="https://example.com/photo.jpg",
order=1,
)
print(file_result)
Note
timeouteste transmis către transportul HTTP folosit dezeep; ajustează valoarea în funcție de mărimea payload-urilor și de rețeaua integrării.session_ideste păstrat intern în wrapper. Codul care folosește clientul apelează doar metode precumsave_property(...)șiadd_file(...).- Context managerul
with ImopediaClient(...)apeleazălogout()la ieșire, inclusiv când apare o excepție în interiorul blocului. - Creează sau actualizează agentul prin
save_agent(...)înainte desave_property(...)dacăAGENT_IDnu există deja pentru agenție. - Continuă cu
add_file(...)doar după ce răspunsul lasave_property(...)confirmă că oferta a fost acceptată. - Erorile SOAP sunt prinse minimal cu
zeep.exceptions.Faultși relansate caRuntimeErrorcu numele operației care a eșuat. add_file(...)primește conținut binar (bytes) și îl encodează în Base64 brut pentru câmpulFILE_BODY, fără prefix de tipdata:image/...;base64,.