Search code examples
pythonrobotframeworkpartial-classes

Appending a method to a class


Hello I have a RobotFramework library for requests /usr/local/lib/python2.7/dist-packages/RequestsLibrary/RequestsKeywords.py

that is missing some code to expose the Digest authentication method in the Python.Requests library. What I want to do is instead of hacking it into /usr/local/lib/python2.7/dist-packages/RequestsLibrary/RequestsKeywords.py

I would like to add if to the code directory i am in and just have it append to the class that is imported

class=RequestsKeywords

In C# etc I would use a partial class but there doesn't seem to be that kind of thing in Python any idea how to procede

here is the code i want to "APPEND" into the /usr/local/lib/python2.7/dist-packages/RequestsLibrary/RequestsKeywords.py library

def create_digest_session(self, alias, url, auth, headers={}, cookies=None, timeout=None, proxies=None, verify=False):

   """ Create Session: create a HTTP session to a server

   `url` Base url of the server

   `alias` Robot Framework alias to identify the session

   `headers` Dictionary of default headers

   `auth` List of username & password for HTTP Digest Auth

   `timeout` connection timeout

   `proxies` proxy server url

   `verify` set to True if Requests should verify the certificate
   """
   digest_auth = requests.auth.HTTPDigestAuth(*auth) if auth else None
   return self._create_session(alias, url, headers, cookie, digest_auth, timeout, proxies, verify)

any suggestions

So my test would look like this below and the python code you specified with the sys.path.append would be in the file RequestsKeywordsLocal.py correct?

*** Settings ***
Suite Teardown    Delete All Sessions
Library           Collections
Library           String
Library           /usr/local/lib/python2.7/dist-packages/RequestsLibrary/RequestsKeywords.py
Library           ./RequestsKeywordsLocal.py 
Library           ./localKeywords.py 
Library           OperatingSystem
Library           BuiltIn

*** Variables ***
${HEADER1}        Content-Type: text/xml; charset=UTF-8
${IP}             172.168.101.139
${UN}             username
${PW}             password

*** Test Cases ***
Check IP valid
    Valid Ip   ${IP}

Get Valid Hostname
    ${host}=    Valid Hostname   ${IP}
    Should Not Be Equal As Strings  ${host}  "noname"

Get With DigestAuth
    [Tags]    get
    Log    Variables
    ${auth}=    Create List    username    password
    Create Digest Session    TerraceQ    https://${IP}    auth=${auth}
    ${resp}=    Get    TerraceQ    /views
    Should Be Equal As Strings    ${resp.status_code}    200
    Should Contain  ${resp.content}  views

Solution

  • You can either subclass:

    class MyNewXThing(XThing):
        def my_added_method(self, x, y, z):
            # ...
    

    And use MyNewXThing instead of XThing throughout your code. Or:

    def my_added_method(self, x, y, z):
        # ...
    XThing.my_added_method = my_added_method
    

    The first option is more flexible, as it does not change XThing for any other code.