Dec-19-2021, 06:47 PM
Hi,
I am trying to work with the epp-python-client which is available on Github, but creating a contact is driving me nuts because I doesn't want to work. I feel there is an issue with the epp-python-client, but I contacted the developer and he doesn't seem to find what the issue is either.
I am using a standard EPP server connection. They all comply with a standard for EPP, so they should be compatible with each other. So I hope that there is someone with a working example that could solve this mystery.
The EPP XML for creating a domain contact looks like this (this is the standard XML input the EPP server expects):
https://github.com/datahaven-net/epp-pyt...nt.py#L327
https://github.com/datahaven-net/epp-pyt...nt.py#L399
Thanks!
I am trying to work with the epp-python-client which is available on Github, but creating a contact is driving me nuts because I doesn't want to work. I feel there is an issue with the epp-python-client, but I contacted the developer and he doesn't seem to find what the issue is either.
I am using a standard EPP server connection. They all comply with a standard for EPP, so they should be compatible with each other. So I hope that there is someone with a working example that could solve this mystery.
The EPP XML for creating a domain contact looks like this (this is the standard XML input the EPP server expects):
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd"> <command> <create> <contact:create xmlns:contact="urn:ietf:params:xml:ns:contact-1.0" xsi:schemaLocation="urn:ietf:params:xml:ns:contact-1.0 contact-1.0.xsd"> <contact:id>sh8013</contact:id> <contact:postalInfo type="int"> <contact:name>John Doe</contact:name> <contact:org>Example Inc.</contact:org> <contact:addr> <contact:street>123 Example Dr.</contact:street> <contact:street>Suite 100</contact:street> <contact:city>Dulles</contact:city> <contact:sp>VA</contact:sp> <contact:pc>20166-6503</contact:pc> <contact:cc>US</contact:cc> </contact:addr> </contact:postalInfo> <contact:voice>+1.7035555555</contact:voice> <contact:fax>+1.7035555556</contact:fax> <contact:email>[email protected]</contact:email> <contact:authInfo> <contact:pw/> </contact:authInfo> </contact:create> </create> <clTRID>30FC8ABC-2FFE-11DE-9786-80000000A8C5</clTRID> </command> </epp>After consulting the developer of the EPP client for Python this is what it probably want how it should be formatted:
print(conn.contact_create( contact_id="some_EPP_ID_1234", voice="+1.7035555555", fax="+1.7035555556", email="[email protected]", contacts=[{ "type": "int", "name": "John Doe", "org":"Example Inc.", "address": { "street":["123 Example Dr.", "Suite 100", ], "city": "Dulles", "sp": "VA", "pc": "20166-6503", "cc": "US", }, }], )) conn.close()But obviously it fails... This is the error I get back from the EPP server:
EPP parser errors: unknown-55812a9e8740:0: Schemas validity error : Element \'{urn:ietf:params:xml:ns:contact-1.0}voice\': This element is not expected. Expected is ( {urn:ietf:params:xml:ns:contact-1.0}postalInfo ).This is how the epp client constructs the create contact:
https://github.com/datahaven-net/epp-pyt...nt.py#L327
def contact_create(self, contact_id, voice=None, fax=None, email=None, contacts=[], auth_info=None, **kwargs): return self.call(cmd=commands.contact.create % dict( cltrid=make_cltrid(), contact_id=contact_id, contact_fields='\n'.join([commands.contact.field1 % f for f in [ {'field': 'voice', 'value': voice, }, {'field': 'fax', 'value': fax, }, {'field': 'email', 'value': email, }, ] if f.get('value')]), postal_infos='\n'.join([ commands.contact.postal_info1 % dict( type=cont['type'], postal_fields='\n'.join([ commands.contact.field2 % pf for pf in [ {'field': 'name', 'value': cont.get('name'), }, {'field': 'org', 'value': cont.get('org'), }, ] if pf.get('value') ]), address_fields='\n'.join([ commands.contact.field3 % dict( field=afield, value=', '.join(avalue) if isinstance(avalue, list) else avalue, ) for (afield, avalue) in cont['address'].items() if avalue ]) ) for cont in contacts ]), auth_info='' if not auth_info else commands.contact.auth_info % auth_info, ), **kwargs)In the RPC module of that client it is specified like this:
https://github.com/datahaven-net/epp-pyt...nt.py#L399
def cmd_contact_create(contact_id, email=None, voice=None, fax=None, auth_info=None, contacts_list=[], **args): """ contacts_list item : { "name": "VeselinTest", "org":"whois", "address": { "street":["Street", "55"], "city": "City", "sp": "Nord Side", "cc": "AI", "pc": "1234AB" } } """ cmd = { 'cmd': 'contact_create', 'args': { 'id': contact_id, 'contacts': [], }, } if voice is not None: cmd['args']['voice'] = voice if fax is not None: cmd['args']['fax'] = fax if email is not None: cmd['args']['email'] = email if auth_info is not None: cmd['args']['auth_info'] = auth_info for cont in contacts_list[:]: international = copy.deepcopy(cont) international['type'] = 'int' if 'name' in international: international['name'] = '%s' % _tr(international['name']) if 'org' in international: international['org'] = '%s' % _tr(international['org']) if 'city' in international['address']: international['address']['city'] = '%s' % _tr(international['address']['city']) if 'sp' in international['address']: international['address']['sp'] = '%s' % _tr(international['address']['sp']) if 'pc' in international['address']: international['address']['pc'] = '%s' % _tr(international['address']['pc']) for i in range(len(international['address']['street'])): international['address']['street'][i] = '%s' % _tr(international['address']['street'][i]) cmd['args']['contacts'].append(international) for cont in contacts_list[:]: loc = copy.deepcopy(cont) loc['type'] = 'loc' if 'name' in loc: loc['name'] = _enc(loc['name']) if 'org' in loc: loc['org'] = _enc(loc['org']) if 'city' in loc['address']: loc['address']['city'] = '%s' % _enc(loc['address']['city']) if 'sp' in loc['address']: loc['address']['sp'] = '%s' % _enc(loc['address']['sp']) if 'pc' in loc['address']: loc['address']['pc'] = '%s' % _enc(loc['address']['pc']) for i in range(len(loc['address']['street'])): loc['address']['street'][i] = '%s' % _enc(loc['address']['street'][i]) cmd['args']['contacts'].append(loc) return run(cmd, **args)Any insights? Ideas?
Thanks!