Git Product home page Git Product logo

python-redfish-library's People

Contributors

4383 avatar bb-ricardo avatar bewing avatar billdodd avatar climberj avatar dirkmueller avatar dsoper2 avatar gkeishin avatar glimchb avatar gweatherby avatar inguin avatar jautor avatar klaas- avatar lijok avatar lindseydonovan avatar lumbajack avatar moshibin avatar mraineri avatar peterkchen2 avatar tomasg2012 avatar vogeltak avatar yergidy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-redfish-library's Issues

pip package at pypi.org is wrong

https://pypi.org/project/redfish/ shows that the current version is 2.0.6. However:

  1. There is no 2.0.6 git tag.

  2. More importantly, the pip content seems to be even older than the 2.0.5 git tag. For example, redfish_client takes a cafile argument in 2.0.5 but not in the pip package.

What git tag version does the '2.0.6' pip package correspond to? Was there a release error?

Proper format for multipart/form-data POST request

Based on Redfish specification, I need to call a multipart/form-data POST request to upload BMC and BIOS files. What is the proper syntax or format to perform such a call from a redfish_client object? I have successfully called the POST request that enters "update mode" and am just having issues making the subsequent call correctly.

I've tried many different iterations of the call but none have worked. Here is my current version:

with open(bmc_path, "rb") as file:
    headers = {"Content-Type": "multipart/form-data"}
    body = {"bmc": (bmc_filename, file)}
    response = redfish_client.post(<API URL>, body=body, headers=headers)

tox unittest fails for Python 3.4

Python 3.4 has reached end-of-life and many recent packages no longer support Python 3.4.

In our tox unittest environment, one such package is testtools. The latest version, 2.4.0, no longer supports Python 3.4, so the environment setup fails as seen in the log output below.

Options to fix:

  1. Disable the 3.4 tox testing
  2. Add a [testenv:py34] clause in tox.ini with explicit version requirements (if we do this, we need to be prepared to update it multiple times as more packages drop 3.4 support)
$ python --version
Python 3.4.8
$ pip --version
pip 18.1 from /home/travis/virtualenv/python3.4.8/lib/python3.4/site-packages/pip (python 3.4)
before_install.1
1.57s$ pip install -U pip
before_install.2
1.44s$ pip install -U setuptools
before_install.3
0.60s$ pip install -U wheel
install
2.07s$ pip install tox-travis .[devel]
3.58s$ tox
py34 create: /home/travis/build/billdodd/python-redfish-library/.tox/py34
py34 installdeps: coverage, fixtures, nose, nose-timer
ERROR: invocation failed (exit code 1), logfile: /home/travis/build/billdodd/python-redfish-library/.tox/py34/log/py34-1.log
================================== log start ===================================
Collecting coverage
  Using cached https://files.pythonhosted.org/packages/b7/65/1a4922e356d7c990a1935f951b6f17906c82ede849d341e62c961decf464/coverage-4.5.4-cp34-cp34m-manylinux1_x86_64.whl
Collecting fixtures
  Using cached https://files.pythonhosted.org/packages/a8/28/7eed6bf76792f418029a18d5b2ace87ce7562927cdd00f1cefe481cd148f/fixtures-3.0.0-py2.py3-none-any.whl
Collecting nose
  Using cached https://files.pythonhosted.org/packages/15/d8/dd071918c040f50fa1cf80da16423af51ff8ce4a0f2399b7bf8de45ac3d9/nose-1.3.7-py3-none-any.whl
Collecting nose-timer
  Using cached https://files.pythonhosted.org/packages/26/6b/6d1cd907c922df136750e098d0f0211e4fe0e8d03dd07c650c9399ca77b4/nose-timer-1.0.0.tar.gz
Collecting six (from fixtures)
  Using cached https://files.pythonhosted.org/packages/ee/ff/48bde5c0f013094d729fe4b0316ba2a24774b3ff1c52d924a8a4cb04078a/six-1.15.0-py2.py3-none-any.whl
Collecting pbr>=0.11 (from fixtures)
  Using cached https://files.pythonhosted.org/packages/96/ba/aa953a11ec014b23df057ecdbc922fdb40ca8463466b1193f3367d2711a6/pbr-5.4.5-py2.py3-none-any.whl
Collecting testtools>=0.9.22 (from fixtures)
  Using cached https://files.pythonhosted.org/packages/1a/d5/d0e0d16478fd4700694673518842be3c159fa08230e377f5f8570c170bbd/testtools-2.4.0-py2.py3-none-any.whl
testtools requires Python '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*' but the running Python is 3.4.8
=================================== log end ====================================
ERROR: could not install deps [coverage, fixtures, nose, nose-timer]; v = InvocationError('/home/travis/build/billdodd/python-redfish-library/.tox/py34/bin/pip install coverage fixtures nose nose-timer', 1)
___________________________________ summary ____________________________________
ERROR:   py34: could not install deps [coverage, fixtures, nose, nose-timer]; v = InvocationError('/home/travis/build/billdodd/python-redfish-library/.tox/py34/bin/pip install coverage fixtures nose nose-timer', 1)
The command "tox" exited with 1.
cache.2
store build cache
Done. Your build exited with 1.

Python module 'six' really required?

As far as I can tell the six module is used to provide Python 2 support.

I'm on CentOS 7, Python 3.6.8 is installed as well as python-six-1.9.0-2.el7 which is for Pyhton 2.

Trying a simple test written in Python 3 I get:

# python3 test.py 
Traceback (most recent call last):
  File "test.py", line 3, in <module>
    import redfish
  File "/tmp/python-redfish-library-master/redfish/__init__.py", line 10, in <module>
    from redfish.rest.v1 import redfish_client
  File "/tmp/python-redfish-library-master/redfish/rest/v1.py", line 23, in <module>
    import six
ModuleNotFoundError: No module named 'six'

In CentOS there is no six module for Python 3, only in EPEL there exists python36-six.noarch.

Is it really necessary to load six inside Python 3 or could this be wrapped inside a version check?

HTTP headers overwritten by library

When using the library to verify proper Redfish service implementation behavior I encountered problem with sending a request with headers which value should not be accepted by the service.

It looks like requests with HTTP headers Accept or OData-Version are overwritten by the library, so I could not find a possibility to send for instance 'Accept': 'application/xml' header which should be rejected by the service, because it's overwritten in library with */*. OData-Version 4.0 also cannot be replaced with a value which could be used to verify service implementation.

Is there any explanation for that ?
Is there any chance to change this behavior or make it somehow configurable?
Or maybe I'm doing something wrong ?
Code example below:

import redfish

REDFISH_OBJ = redfish.redfish_client(
        base_url='https://10.172.201.115',
        username='admin', password='admin',
        default_prefix='/redfish/v1')

REDFISH_OBJ.login()
iheaders = {'Accept': 'application/xml'}
response = REDFISH_OBJ.get('/redfish/v1/Managers', headers=iheaders)
print (response)
REDFISH_OBJ.logout()

POST complaining about malformed JSON

A simple code to do action on a given target. I'm not sure if there is problem in my example code there.. via request API can do correctly but with the redfish API, i seem to see this JSON malform error.

Resource meta data and target info snippet

{
  "@odata.context": "/redfish/v1/$metadata#ComputerSystem.ComputerSystem",
  "@odata.id": "/redfish/v1/Systems/1",
  "@odata.type": "#ComputerSystem.v1_3_0.ComputerSystem",
  "Actions": {
    "#ComputerSystem.Reset": {
      "[email protected]": [
        "On",
        "ForceOff",
        "GracefulRestart",
        "GracefulShutdown"
      ],
      "target": "/redfish/v1/Systems/1/Actions/ComputerSystem.Reset"
    }
  }

Sample code to do POST operation

        session = redfish.redfish_client("https://xx.xx.xx.xx", "root", "mypassword", "/redfish/v1")
        session.login(auth=redfish.AuthMethod.SESSION)
        arg = { "ResetType": "GracefulShutdown" }
        response = session.post("/redfish/v1/Systems/1/Actions/ComputerSystem.Reset", args=arg)
        return response

What i get is this

400

{
  "error": {
    "@Message.ExtendedInfo": [
      {
        "@odata.type": "/redfish/v1/$metadata#Message.v1_0_0.Message",
        "Message": "The request body submitted was malformed JSON and could not be parsed by the receiving service.",
        "MessageArgs": [],
        "MessageId": "Base.1.4.0.MalformedJSON",
        "Resolution": "Ensure that the request body is valid JSON and resubmit the request.",
        "Severity": "Critical"
      }
    ],
    "code": "Base.1.4.0.MalformedJSON",
    "message": "The request body submitted was malformed JSON and could not be parsed by the receiving service."
  }
}

Tried manually using request curl

$ curl -k -H "X-Auth-Token: N85b9ii31Ea9rjvjLnJH" -X POST https://${BMC_IP}/redfish/v1/Systems/1/Actions/ComputerSystem.Reset -d '{"ResetType": "GracefulShutdown"}'
{
  "@Message.ExtendedInfo": [
    {
      "@odata.type": "/redfish/v1/$metadata#Message.v1_0_0.Message",
      "Message": "Successfully Completed Request",
      "MessageArgs": [],
      "MessageId": "Base.1.4.0.Success",
      "Resolution": "None",
      "Severity": "OK"
    }
  ]
}

Works there..

Unable to properly construct query parameters

The current library expects query parameters to be passed into GET requests using the "args" argument. The value passed is a dictionary of each query parameter where the name is the parameter name and the value is parameter argument. Underneath the covers, it calls "urlencode" to process the dictionary to produce the string to append to the URL. For example:

query = { "$filter": "Id eq 'Administrator'" }
filter_resp = redfish_obj.get( "/redfish/v1/AccountService/Roles", args = query )

However, this doesn't get encoded properly; the spaces in the example get encoded as + instead of %20, which makes the parameter argument invalid. There have been issues raised about this, and urlencode can take an optional "quote_via" argument to change the behavior. But since we're using the "six" module for compatibility with Python2, this argument isn't available.

Some options to consider:

  • Do we drop Python2 at this point? Python2 hit EOL January 2020, and many organizations are pledging to drop support for Python2.
  • Do we write our own "urlencode" function for this to maintain Python2 support?

What is the default_prefix for?

Can someone please point me to documentation on default_prefix? I'm fairly new to the Redfish APIs not sure I understand what is it for. My code seems to work fine without setting the prefix. Thanks.

python2.7 import redfish On failure!!

my env :
-- redfish.version
'2.0.8'


my code:

library/blob/master/LICENSE.md
import sys
import redfish

login_host = "https://1.2.2.2"
login_account = "xxxt"
login_password = "xxx5"

REDFISH_OBJ = redfish.redfish_client(base_url=login_host, username=login_account,password=login_password)
REDFISH_OBJ.login(auth="session")
response = REDFISH_OBJ.get("/redfish/v1/systems/1", None)
sys.stdout.write("%s\n" % response)
REDFISH_OBJ.logout()


my error

Traceback (most recent call last):
File "get_power_state.py", line 48, in get_power_state
password=login_password, default_prefix='/redfish/v1')
File "/usr/lib/python2.7/site-packages/redfish/rest/v1.py", line 1058, in redfish_client
max_retry=max_retry)
File "/usr/lib/python2.7/site-packages/redfish/rest/v1.py", line 983, in init
max_retry=max_retry)
File "/usr/lib/python2.7/site-packages/redfish/rest/v1.py", line 453, in init
self.get_root_object()
File "/usr/lib/python2.7/site-packages/redfish/rest/v1.py", line 584, in get_root_object
raise excp
RetriesExhaustedError

Example using ContextManager is helpful

It will be very helpful to give this example how to use redfish with ContextManager :

with  redfish.redfish_client('https://192.168.1.100', 'admin', 'password') as REDFISH_OBJ:
    response = REDFISH_OBJ.get("/redfish/v1/systems/1")
    print response.text

It will save login and with suto-logout in case of error... No need in additional exception handling with finally

Logout doesn't handle bad or dummy Delete request

A couple of inputs on handling the log out:

  1. It doesn't throw an error if the session location doesn't exist (Use case where the server is restarted and old session are purged)

  2. It allows a user to set any dummy id

As an end user, we would want to know for sure if the session is deleted for real or not.

Example:

import redfish

robj = redfish.redfish_client(base_url="https://xx.xx.xx.xx/",
                       username="root",
                       password="myPassword",
                       default_prefix='/redfish/v1')
robj.login(auth="session")
robj.set_session_location("dummy")
print("Session location: %s" % robj.get_session_location())
robj.logout()

Output:

$python sample.py 
Session location: dummy
$

It just says worked but on decoding the code how the logout handles here is what we should probably handle.

Now, I added debug exception code and response checks in redfish/rest/v1.py

Exception:

class BadRequestError(Exception):
    """Bad Request to server."""
    pass

logout response delete check:

            session_loc = self.__session_location.replace(self.__base_url, '')
            print("DEBUG: session_loc: %s" % session_loc)

            resp = self.delete(session_loc)
            # DEBUG: Added Response status check.
            if resp.status != 200:
                print(resp.text)
                raise BadRequestError("HTTP Bad Request"
                                               "return code: %d" % resp.status)
python sample.py 
Session location: dummy
DEBUG: session_loc: dummy
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>

Traceback (most recent call last):
  File "sample.py", line 14, in <module>
    robj.logout()
  File "/usr/local/lib/python2.7/dist-packages/redfish/rest/v1.py", line 893, in logout
    "return code: %d" % resp.status)
redfish.rest.v1.BadRequestError: HTTP Bad Requestreturn code: 400

Unable to logout()

Using python 3.5.2 I set up a client;
rclient = redfish.redfish_client("https://172.17.45.207:8098","Admin","administrator")
and logged in;
rclient.login()
then tried to logout()

rclient.logout()
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python3.5/dist-packages/redfish/rest/v1.py", line 946, in logout
"return code: %d" % (session_loc, resp.status))
redfish.rest.v1.BadRequestError: Invalid session resource: SessionService/Sessions/c48228132d1a1941, return code: 404

I created a new module logoff();

    def logoff(self):
        """ Logout of session. YOU MUST CALL THIS WHEN YOU ARE DONE TO FREE"""
        """ UP SESSIONS"""
        if self.__session_key:
            session_loc = "{}{}".format(self.default_prefix,self.__session_location)
            resp = self.delete(session_loc)
            if resp.status not in [200, 202, 204]:
                raise BadRequestError("Invalid session resource: %s, "\
                                   "return code: %d" % (session_loc, resp.status))

            LOGGER.info("User logged out: %s", resp.text)

            self.__session_key = None
            self.__session_location = None
            self.__authorization_key = None

which is a copy of logout() with the session_log modified. This worked for me. But I can't say for certain if the failure was due to the redfish module or the redfish implementation on the product I was testing.

Patch Problem

url = "http://IP/redfish/v1/TaskService"
arg = {"ServiceEnabled":"false"}

session = redfish.redfish_client("http://IP", "username", "password", "/redfish/v1")
session.login(auth=redfish.AuthMethod.SESSION)
respose = session.patch("redfish/v1/TaskService", args=arg)
print session.get("/redfish/v1/TaskService")

This is my code. I try to update something in server. However, the data was not changed. Did I do something wrong. Plz help me.
default
the output is above

Getting the each Network Adapters MAC addresses for Cisco UCS Servers

Is there a method to identify the MAC address of the each Network adapter of the Cisco UCS server.
I was trying to automate PXE boot tasks and getting these MAC addresses is quite important.
I was not able to find a proper method to fetch the MAC address of each network adapter using redfish API.

Does anyone has any idea regarding this ?

Can't terminate a redfish session via .logout()

I'm using the redfish library to manage the Cisco IMC on class C UCS servers. The .logout() function fails both if I call it explicitly or if it is invoked via context manager. Strangely, I can terminate the session just fine via custom code with requests.

from redfish.rest.v1 import HttpClient
from requests import delete
from urllib3 import disable_warnings, exceptions

disable_warnings(exceptions.InsecureRequestWarning)


class CIMC(HttpClient):
    def __enter__(self):
        self.login()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        try:
            self.logout()
        except Exception as e:
            print(e)
            d = delete(url=f'{self.get_base_url() + self.get_session_location()}',
                       headers={'X-Auth-Token': self.get_session_key()}, verify=False)
            if d.status_code in [200, 202, 204]:
                print('Logged out via requests')
            else:
                print(d.reason)
        else:
            print('Logged out via redfish library')


login_host = "https://x.x.x.x"
login_account = "user"
login_password = "password"

with CIMC(base_url=login_host, username=login_account, password=login_password, max_retry=2) as cimc_cx:
    b = cimc_cx.get("/redfish/v1/Managers/CIMC")
    print(b)

This is only a workaround, but I would like to know why the native logout() function fails.

Here is the printout my context manager __exit__ function:

Invalid session resource: /redfish/v1/SessionService/Sessions/3336, return code: 404
Logged out via requests

As you can tell, logout was performed via requests using the parameters that would be used via the native logout() function. I doubt that the issue is the redfish implementation on the CIMC.

Is there a way to identify the Server Vendor type using redfish API

I am trying to identify the Server vendor type(Dell or Cisco or HP) via Redfish API which in subsequent performs tasks based on that.
I have verified "/redsfish/v1" for Cisco and Dell servers but haven't got a consistent data on identifying the server vendor type.
Is there any better way to identify the Server vendor type?

Changing the SNMP user credentials for the CISCO UCS Servers

Is there a way to change the SNMP user password for the Cisco UCS servers.
I have almost more than 50 servers and looking for a better way to do it instead of doing it manually from dashboard.
Anyone please let me know is there any way to do the same.

Regards,
Naga Phani.

AttributeError: module 'redfish' has no attribute 'redfish_client'

Dear SIr:
I got an error said the module 'redfish' has no attribute 'redfish_client' and below is my env. Is there something wrong of my env?

python -V
Python 3.9.4

cat quickstart.py

# Copyright Notice:
# Copyright 2016-2021 DMTF. All rights reserved.
# License: BSD 3-Clause License. For full text see link:
# https://github.com/DMTF/python-redfish-library/blob/master/LICENSE.md

import sys
import redfish

# When running remotely connect using the address, account name,
# and password to send https requests
login_host = "https://172.17.21.120"
login_account = "admin"
login_password = "password"

## Create a REDFISH object
REDFISH_OBJ = redfish.redfish_client(base_url=login_host, username=login_account,
                          password=login_password, default_prefix='/redfish/v1')

# Login into the server and create a session
REDFISH_OBJ.login(auth="session")

# Do a GET on a given path
response = REDFISH_OBJ.get("/redfish/v1/systems/1", None)

# Print out the response
sys.stdout.write("%s\n" % response)

# Logout of the current session
REDFISH_OBJ.logout()

Result:
python quickstart.py
Traceback (most recent call last):
File "/Users/ch.huang789/Python/python-redfish-library/examples/quickstart.py", line 16, in
REDFISH_OBJ = redfish.redfish_client(base_url=login_host, username=login_account,
AttributeError: module 'redfish' has no attribute 'redfish_client'

Defining a timeout

It would be nice to define a short timeout in case of some BMCs not responding or being broken.

KeyError: 'Links'

Info

Huawei server
redfish v1

Exception result

Traceback (most recent call last):
File "/home/chao/PycharmProjects/texx/rfish.py", line 7, in
REDFISH_OBJ = redfish.redfish_client(base_url=login_host, username=login_account, password=login_password, default_prefix=default_prefix)
File "/home/chao/Desktop/python-redfish-library/src/redfish/rest/v1.py", line 954, in redfish_client
default_prefix=default_prefix, sessionkey=sessionkey)
File "/home/chao/Desktop/python-redfish-library/src/redfish/rest/v1.py", line 894, in init
self.login_url = self.root.Links.Sessions['@odata.id']
KeyError: 'Links'

Description

login_host = https://x.x.x.x
i'm sure username and password correctly
default_prefix = /redfish/v1

Remove old library dependency - urlparse2

urlparse2 is an unmaintained library - last commit is 6 years old.
The library is not python3 compatible (at least it's dependecy - recordtype library).

HP's fork of python-redfish-library dropped urlparse2 last year...
HewlettPackard#28

Please, remove this dependency and use built-in functions to parse URL.
Thanks.

replace outdated urlparse2 by urllib3?

Hi,
Aqua security scanner highlights urlparse2/urlparse1.py as being affected by CVE-2019-10160 and CVE-2019-9636. I see redfish is using this library in only a single place (RmcClient.get_cache_dirname), and wonder if you could replace this with a more maintained library like urllib3 or something? Happy to file a PR if you think this is sensible..

Two problems about using redfish==2.0.2

For the following code(master/src/redfish/rest/v1.py), I met two problems when using redfish==2.0.2.
These two problems didn't existed in the previous version 2.0.0.

line:(888-890)
"
if resp.status != 200:
raise BadRequestError("Invalid session resource: %s, "
"return code: %d" % session_loc, resp.status)
"

  1. First question:
    On line 888 of the code, logout of session failure when status code is not equal to 200. What about status like 204? Is it also a failure?
    Based on HTTP protocol, 2xx all are treated as sucess. Hope normally status code like 202/204 can be treated as sccess.

  2. Second question:
    When I call logout() to logout of session, our status code is 204, expected exception is not raised, below Typeerror exception is displayed.
    TypeError: not enough arguments for format string

I think there is an error in the 890 row of the modified code, One '%' can not format multiple strings.
When I change "return code: %d" % session_loc, resp.status) to "return code: %d" %(session_loc, resp.status)), Typeerror problem is resolved.

Please help to clarify it and fix it if they are really bugs.

"python-redfish-library" is not able to follow HTTP: 303 (Location Header) sent by Redfish Server correctly

Used following snippet:

import redfish
redfish_host = "https://{}".format("192.168.40.141")
redfish_account = "root"
redfish_password = "root"

## get redfish handle
redfish_obj = redfish.redfish_client(base_url=redfish_host, username=redfish_account, password=redfish_password, default_prefix='/redfish/v1')
redfish_obj.login(auth="basic")
for i in range(1):
    r = redfish_obj.post("/redfish/v1/Systems/000000000000/Actions/ComputerSystem.Reset", body={})
    print r.status
    print r.dict

Now, Redfish Library doing POST correctly to Redfish Server and Server sending it a 303 (Redirection) Response with TaskMonitor URI (/redfish/v1/TaskMonit/92a8da74-d8e9-485f-ba5d-5bd82a87e706) in "Location Header" and Now as per HTTP:303 Rule, Redfish Library has to do "GET" on sent TaskMonitor URI by Redfish Server but instead its doing "POST" only on TaskMonitor URI to Server and end-up getting "Method Not Allowed" (HTTP:405).
(https://en.wikipedia.org/wiki/HTTP_303)

Is it a bug or really can be fixed by some alternatives, Please do let me know at very earliest.

Tried same with POSTMAN, redfishtool and CURL, everybody is able to tackle 303 correctly for Task Based POST but redfish library not and Hence Raising a BUG here.

e.g. CURL Response: (Expected Query/Responses)
curl -L -k -u root:fungible -i -H "Content-Type: application/json" -d {} https://192.168.40.141/redfish/v1/Systems/000000000000/Actions/ComputerSystem.Reset

HTTP/1.1 303 See Other
Location: /redfish/v1/TaskMonit/92a8da74-d8e9-485f-ba5d-5bd82a87e706
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
OData-Version: 4.0
Cache-Control: no-cache
Cache-Control: no-store, no-cache
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
X-UA-Compatible: IE=11
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Pragma: no-cache
Content-Security-Policy: default-src 'none'; frame-src 'self' data:; style-src 'self'; font-src 'self'; script-src 'self'; object-src 'self'; connect-src 'self' wss://:/mi_ws_msg_service; img-src 'self'; child-src 'self'
Content-Length: 154
Date: Mon, 26 Jan 1987 04:09:49 GMT
Server: lighttpd/1.4.52

HTTP/1.1 202 Accepted
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
OData-Version: 4.0
Cache-Control: no-cache
Cache-Control: no-store, no-cache
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
X-UA-Compatible: IE=11
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Pragma: no-cache
Content-Security-Policy: default-src 'none'; frame-src 'self' data:; style-src 'self'; font-src 'self'; script-src 'self'; object-src 'self'; connect-src 'self' wss://:/mi_ws_msg_service; img-src 'self'; child-src 'self'
Content-Length: 554
Date: Mon, 26 Jan 1987 04:09:49 GMT
Server: lighttpd/1.4.52

{"@odata.id":"/redfish/v1/TaskMonit/92a8da74-d8e9-485f-ba5d-5bd82a87e706","Id":"1","Name":"Task 1","TaskState":"Running","TaskStatus":"OK","TaskMonitor":"/redfish/v1/TaskMonit/92a8da74-d8e9-485f-ba5d-5bd82a87e706","Messages":[{"@odata.type":"#Message.v1_0_8.Message","MessageId":"Common.1.0.0.UpdateServiceUpdateProgress","Message":"Action: �+Z in Progress","MessageArgs":["�+Z"],"Severity":"OK","Resolution":"None."}],"@odata.type":"#Task.v1_4_3.Task","@odata.context":"/redfish/v1/$metadata#Task.Task","@odata.etag":"ea3620b0509a49127ab30f3e993fe4a0"}

ILO5 Remote end closed connection without response

Executing commands against ILO5 failed as the 'Remote end closed connection without response'. When checking the sessions, I can see a session successfully created and is still active, appears any connections after are failing:

redfish_obj = redfish.redfish_client(base_url=host_url, username=svc_account, \
                          password=svc_password, max_retry=1, timeout=120, default_prefix='/redfish/v1')

redfish_obj.login(auth='session')

redfish_obj.get('/redfish/v1')

Any guidance on how to check this, the same script works fine against ILO4.

Traceback (most recent call last):
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\redfish\rest\v1.py", line 814, in _rest_request
    resp = self._conn.getresponse()
  File "C:\Program Files (x86)\Python37-32\lib\http\client.py", line 1321, in getresponse
    response.begin()
  File "C:\Program Files (x86)\Python37-32\lib\http\client.py", line 296, in begin
    version, status, reason = self._read_status()
  File "C:\Program Files (x86)\Python37-32\lib\http\client.py", line 265, in _read_status
    raise RemoteDisconnected("Remote end closed connection without"
http.client.RemoteDisconnected: Remote end closed connection without response

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\redfish\rest\v1.py", line 617, in get
    headers=headers)
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\redfish\rest\v1.py", line 1013, in _rest_request
    args=args, body=body, headers=headers)
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\redfish\rest\v1.py", line 878, in _rest_request
    raise_from(RetriesExhaustedError(), cause_exception)
  File "<string>", line 3, in raise_from
redfish.rest.v1.RetriesExhaustedError

TCP connection is closed after each response

After each REST request (after receiving the response) the TCP connection to the server is closed. Is this intentional?

This happens here:

self.__destroy_connection()

Any "Connection: Keep-Alive" is not honored. Note that a bit earlier in the code it is honored:
if resp.getheader('Connection') == 'close':

Closing the connection every time is quite inefficient, as every subsequent request then requires setting up a new TCP connection, and in case of https, repeating the SSL/TLS negotiation.

On my test system, keeping the connection open instead of closing it, reduces execution time for https://github.com/DMTF/Redfish-Tacklebox/blob/master/scripts/rf_sensor_list from ~25 seconds to ~12 seconds.

redfish.rest.v1.RetriesExhaustedError

While running the quickstart.py example i am getting the following error

$python3 quickstart.py

Traceback (most recent call last):
File "quickstart.py", line 16, in
password=login_password, default_prefix='/redfish/v1')
File "/usr/local/lib/python3.5/dist-packages/redfish/rest/v1.py", line 1027, in redfish_client
max_retry=max_retry)
File "/usr/local/lib/python3.5/dist-packages/redfish/rest/v1.py", line 952, in init
max_retry=max_retry)
File "/usr/local/lib/python3.5/dist-packages/redfish/rest/v1.py", line 422, in init
self.get_root_object()
File "/usr/local/lib/python3.5/dist-packages/redfish/rest/v1.py", line 553, in get_root_object
raise excp
File "/usr/local/lib/python3.5/dist-packages/redfish/rest/v1.py", line 551, in get_root_object
resp = self.get('%s%s' % (self.__url.path, self.default_prefix))
File "/usr/local/lib/python3.5/dist-packages/redfish/rest/v1.py", line 585, in get
headers=headers)
File "/usr/local/lib/python3.5/dist-packages/redfish/rest/v1.py", line 979, in _rest_request
args=args, body=body, headers=headers)
File "/usr/local/lib/python3.5/dist-packages/redfish/rest/v1.py", line 844, in _rest_request
raise RetriesExhaustedError()

I am using the redfish version 2.0.7. I am trying to test the redfish api on a remote host pc.The login credentials are correct since i am able to do ssh to the remote PC. Is there any host PC requirements or something??

NO_PROXY variable not working

Hi
I have a proxy for internet, yum, ...
Connection to redfish servers are diret.
So I set 3 variable HTTP_PROXY, HTTPS_PROXY and NO_PROXY
NO_PROXY does contain redfish server IP addresses.
I tried the quickstart.py example
it works only if i unset HTTPS_PROXY.

image

Could you take care of NO_PROXY env. variable ?

Best regards,
Francine

Switch from basic auth to session by default

Currently the login function will use basic auth by default unless otherwise specified. It would be good to use session auth so that it simplifies code leveraging the with statement. Session authentication should be preferential in the majority of cases, but need to understand why basic auth was originally used as the default.

Initialize redfish object failed after logging config changes

Python 3.6.3 |Anaconda, Inc.| (default, Oct 15 2017, 07:29:16) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.

import logging
import redfish
logging.basicConfig(level=logging.DEBUG)
redfish.redfish_client("https://10.239.91.40")
DEBUG:redfish.rest.v1:HTTP REQUEST: GET
PATH: /redfish/v1/
BODY: None
INFO:redfish.rest.v1:Attempt 1 of /redfish/v1/
INFO:redfish.rest.v1:Response Time to /redfish/v1/: 0.10654076165774838 seconds.
Traceback (most recent call last):
File "", line 1, in
File "C:\Anaconda3\lib\site-packages\redfish-2.0.0-py3.6.egg\redfish\rest\v1.py", line 953, in redfish_client
File "C:\Anaconda3\lib\site-packages\redfish-2.0.0-py3.6.egg\redfish\rest\v1.py", line 891, in init
File "C:\Anaconda3\lib\site-packages\redfish-2.0.0-py3.6.egg\redfish\rest\v1.py", line 400, in init
File "C:\Anaconda3\lib\site-packages\redfish-2.0.0-py3.6.egg\redfish\rest\v1.py", line 515, in get_root_object
File "C:\Anaconda3\lib\site-packages\redfish-2.0.0-py3.6.egg\redfish\rest\v1.py", line 513, in get_root_object
File "C:\Anaconda3\lib\site-packages\redfish-2.0.0-py3.6.egg\redfish\rest\v1.py", line 547, in get
File "C:\Anaconda3\lib\site-packages\redfish-2.0.0-py3.6.egg\redfish\rest\v1.py", line 918, in _rest_request
File "C:\Anaconda3\lib\site-packages\redfish-2.0.0-py3.6.egg\redfish\rest\v1.py", line 785, in _rest_request
AttributeError: 'HTTPMessage' object has no attribute 'headers'

Setting capath and cafile to None still verifies the SSL certificate in CentOS 7.6

>>> import redfish
>>> redfish.redfish_client("https://myhost", "username", "password", capath=None, cafile=None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/site-packages/redfish/rest/v1.py", line 1061, in redfish_client
    max_retry=max_retry)
  File "/usr/lib/python2.7/site-packages/redfish/rest/v1.py", line 986, in __init__
    max_retry=max_retry)
  File "/usr/lib/python2.7/site-packages/redfish/rest/v1.py", line 454, in __init__
    self.get_root_object()
  File "/usr/lib/python2.7/site-packages/redfish/rest/v1.py", line 585, in get_root_object
    raise excp
redfish.rest.v1.RetriesExhaustedError

The requests library sheds some more light on the matter:

>>> import requests
>>> request.get("https://myhost")
requests.exceptions.SSLError: hostname 'myhost' doesn't match u'Different Certificate Name'

So we're failing due to a mismatch between the certificate CN and the server name.

Digging deeper, I looked at RestClientBase.__init_connection and saw this snippet:

        if url.scheme.upper() == "HTTPS":
            if sys.version_info < (2, 7, 9):
                self._conn = http_client.HTTPSConnection(url.netloc,
                                                         timeout=self._timeout)
            else:
                if self.cafile or self.capath is not None:
                    ssl_context = ssl.create_default_context(
                        capath=self.capath, cafile=self.cafile)
                else:
                    ssl_context = ssl._create_unverified_context()
                self._conn = http_client.HTTPSConnection(url.netloc,
                                                         context=ssl_context,
                                                         timeout=self._timeout)

This makes sense, since the docs clearly state that the context argument has been added in Python 2.7.9:

Changed in version 2.7.9: context was added.

However, CentOS 7.6 has Python 2.7.5 with backports from later versions:

$ rpm -q python
python-2.7.5-76.el7.x86_64
>>> import sys
>>> sys.version_info
sys.version_info(major=2, minor=7, micro=5, releaselevel='final', serial=0)
>>> import httplib, inspect
>>> "context" in inspect.getargspec(httplib.HTTPSConnection.__init__).args
True

This means that the code in redfish thinks that the installed python doesn't have the certificate hostname checking and doesn't pass context=ssl._create_unverified_context(), while the argument is actually supported so it behaves like python >= 2.7.9.

Release on github and PyPI

Currently the project is not released on PyPI nor it has a tarball in github. Is it possible to create a tarball release?

Unable to logout

Hello, I was testing this library against my redfish server. While running the example, I encountered this error:

{'@odata.context': '/redfish/v1/$metadata#Session.Session',
'@odata.id': '/redfish/v1/SessionService/Sessions/m9hv9CudGZ',
'@odata.type': '#Session.v1_0_2.Session',
'Description': 'Manager User Session',
'Id': 'm9hv9CudGZ',
'Name': 'User Session',
'UserName': 'root'}
<redfish.rest.v1.RestResponse object at 0x7f0a83412a90>
200
Strict-Transport-Security max-age=31536000; includeSubdomains; preload
X-UA-Compatible IE=11
X-Frame-Options DENY
X-XSS-Protection 1; mode=block
X-Content-Security-Policy default-src 'self'
Pragma no-cache
Cache-Control no-Store,no-Cache
Server iBMC
Date Wed, 23 May 2018 22:24:42 GMT
Content-Length 0
connection Keep-Alive

Traceback (most recent call last):
File "/home/user/example.py", line 44, in
REDFISH_OBJ.logout()
File "/home/user/python-redfish-library/src/redfish/rest/v1.py", line 882, in logout
session_loc = self.__session_location.replace(self.__base_url, '')
AttributeError: 'NoneType' object has no attribute 'replace'

What I can gather is: The http response object is not providing a location header
I'm able to create and delete sessions using curl (https://github.com/HewlettPackard/ilo-rest-api-docs/blob/master/source/includes/_ilo5_authentication.md)
If I try another auth method, such as "basic" there is no error.

I'm still debugging what exactly is happening inside http\client.py (HTTPSconnection).

Unable to post body with boolen data

body = {"Enabled": true}
foo = redfish_client.patch('/redfish/v1/AccountService/Accounts/3', body=body)

Python will throw "NameError: name 'true' is not defined" error

How to set the body data in this case?

Decompression errors

Python 3.6
Every response with Content-Encoding gzip results in the following error

>>> from redfish import redfish_client
>>> server = redfish_client('http://192.168.200.216', 'redfish_admin', 'Redfish!')
>>> server.login(auth='session')
>>> schema = server.get('/redfish/v1/SchemaStore/en/ComputerSystem.json/')
Error occur while decompressing body: can't concat str to bytes
Traceback (most recent call last):
  File "C:\Users\gecase\AppData\Local\Programs\Python\Python37-32\lib\site-packages\redfish\rest\v1.py", line 795, in _r
est_request
    restresp.text = decompressedfile.read()
  File "C:\Users\gecase\AppData\Local\Programs\Python\Python37-32\lib\gzip.py", line 276, in read
    return self._buffer.read(size)
  File "C:\Users\gecase\AppData\Local\Programs\Python\Python37-32\lib\gzip.py", line 463, in read
    if not self._read_gzip_header():
  File "C:\Users\gecase\AppData\Local\Programs\Python\Python37-32\lib\gzip.py", line 406, in _read_gzip_header
    magic = self._fp.read(2)
  File "C:\Users\gecase\AppData\Local\Programs\Python\Python37-32\lib\gzip.py", line 91, in read
    self.file.read(size-self._length+read)
TypeError: can't concat str to bytes

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\gecase\AppData\Local\Programs\Python\Python37-32\lib\site-packages\redfish\rest\v1.py", line 578, in ge
t
    headers=headers)
  File "C:\Users\gecase\AppData\Local\Programs\Python\Python37-32\lib\site-packages\redfish\rest\v1.py", line 964, in _r
est_request
    args=args, body=body, headers=headers)
  File "C:\Users\gecase\AppData\Local\Programs\Python\Python37-32\lib\site-packages\redfish\rest\v1.py", line 799, in _r
est_request
    raise DecompressResponseError()
redfish.rest.v1.DecompressResponseError

Support for Task handling

Currently if a service responds with 202 Accepted, it passes this back up to the caller and the caller is responsible for monitoring the Task until it's complete. Would like to discuss if it's worth adding Task management internal to the library so all tools don't need to duplicate Task logic.

redfish.rest.v1.RetriesExhaustedError

When I try to run one_time_boot.py which locates DMTF/Redfish-Usecase-Checkers the following errors occour.
sudo /usr/local/python3.5/bin/python3.5 one_time_boot.py 10.104.195.19 Once Pxe -u XXX -p XXX
[sudo] password for zhangjn:
Traceback (most recent call last):
File "one_time_boot.py", line 225, in
sys.exit(main(sys.argv))
File "one_time_boot.py", line 197, in main
base_url=args.rhost, username=args.user, password=args.password, default_prefix="/redfish/v1")
File "/usr/local/python3.5/lib/python3.5/site-packages/redfish/rest/v1.py", line 1058, in redfish_client
max_retry=max_retry)
File "/usr/local/python3.5/lib/python3.5/site-packages/redfish/rest/v1.py", line 983, in init
max_retry=max_retry)
File "/usr/local/python3.5/lib/python3.5/site-packages/redfish/rest/v1.py", line 453, in init
self.get_root_object()
File "/usr/local/python3.5/lib/python3.5/site-packages/redfish/rest/v1.py", line 584, in get_root_object
raise excp
File "/usr/local/python3.5/lib/python3.5/site-packages/redfish/rest/v1.py", line 582, in get_root_object
resp = self.get('%s%s' % (self.__url.path, self.default_prefix))
File "/usr/local/python3.5/lib/python3.5/site-packages/redfish/rest/v1.py", line 616, in get
headers=headers)
File "/usr/local/python3.5/lib/python3.5/site-packages/redfish/rest/v1.py", line 1010, in _rest_request
args=args, body=body, headers=headers)
File "/usr/local/python3.5/lib/python3.5/site-packages/redfish/rest/v1.py", line 875, in _rest_request
raise RetriesExhaustedError()
redfish.rest.v1.RetriesExhaustedError

And I try to send redfish api with curl. It returns OK.

curl -v --insecure https://10.104.197.130/redfish/v1/

  • About to connect() to 10.104.197.130 port 443 (#0)
  • Trying 10.104.197.130...
  • Connected to 10.104.197.130 (10.104.197.130) port 443 (#0)
  • Initializing NSS with certpath: sql:/etc/pki/nssdb
  • skipping SSL peer certificate verification
  • SSL connection using TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  • Server certificate:
  • subject: CN=XCC-7Y51-1234567890,O=Lenovo,L=RTP,ST=NC,C=US
  • start date: Jun 03 11:14:28 2019 GMT
  • expire date: May 31 11:14:28 2029 GMT
  • common name: XCC-7Y51-1234567890
  • issuer: CN=XCC-7Y51-1234567890,O=Lenovo,L=RTP,ST=NC,C=US

GET /redfish/v1/ HTTP/1.1
User-Agent: curl/7.29.0
Host: 10.104.197.130
Accept: /

< HTTP/1.1 200 OK
< Date: Fri, 28 Jun 2019 18:06:54 GMT
< Content-Type: application/json
< Transfer-Encoding: chunked
< Connection: keep-alive
< Link: </redfish/v1/schemas/ServiceRoot.v1_5_1.json>; rel="describedby"; type="application/json"
< ETag: "1fb8c1bd650f93f0f985392d6afa835e"
< Allow: HEAD
< Allow: GET
< OData-Version: 4.0
< Content-Language: en
< Cache-Control: no-store
< Server: XCC Web Server
< Strict-Transport-Security: max-age=31536000; includeSubDomains
< Content-Security-Policy: default-src 'self'; connect-src *; script-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; font-src 'self' data:; child-src 'self'; object-src 'none'
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< Cache-Control: no-cache, no-store, must-revalidate, private
< X-Frame-Options: DENY
<
{"Chassis":{"@odata.id":"/redfish/v1/Chassis"},"Id":"RootService","Links":{"Sessions":{"@odata.id":"/redfish/v1/SessionService/Sessions"}},"Managers":{"@odata.id":"/redfish/v1/Managers"},"@odata.context":"/redfish/v1/$metadata#ServiceRoot.ServiceRoot","Systems":{"@odata.id":"/redfish/v1/Systems"},"TelemetryService":{"@odata.id":"/redfish/v1/TelemetryService"},"UpdateService":{"@odata.id":"/redfish/v1/UpdateService"},"UUID":"AB48330E-0DCF-41D4-A0FA-1DA5E25DABA9","Vendor":"Lenovo","Name":"Root Service","@odata.type":"#ServiceRoot.v1_5_1.ServiceRoot","SessionService":{"@odata.id":"/redfish/v1/SessionService"},"Description":"This resource is used to represent a service root for a Redfish implementation.","@odata.etag":""1fb8c1bd650f93f0f985392d6afa835e"","AccountService":{"@odata.id":"/redfish/v1/AccountService"},"@odata.id":"/redfish/v1/"}

  • Connection #0 to host 10.104.197.130 left intact

Socks proxy

Any chance to implement proxy (SOCKS5) support?

So trying to use the example and I keep getting time outs.

So I get a timeout response - can go to the browser and it all works fine, any hints?

`import sys
import redfish

login_host = "https://10.250.2.2"
login_account = "root"
login_password = "tester"

sys.stdout.write("Before OBJ host=%s account=%s password=%s\n" % (login_host, login_account, login_password))
REDFISH_OBJ = redfish.redfish_client(base_url=login_host, username=login_account, password=login_password,
timeout=5, max_retry=3, default_prefix='/redfish/v1/Systems')
sys.stdout.write("After OBJ\n")

REDFISH_OBJ.login(auth="session")

response = REDFISH_OBJ.get("/redfish/v1/Systems", None)

sys.stdout.write("%s\n" % response)

REDFISH_OBJ.logout()
`

Example using ContextManager is helpful

It will be very helpful to give this example how to use redfish with ContextManager :

with  redfish.redfish_client('https://in-g0001-bmca', 'admin', 'password') as REDFISH_OBJ:
    response = REDFISH_OBJ.get("/redfish/v1/systems/1")
    print response.text

Problem using skip and expand params

Hello

I'm need some help. On my redfish API i have 1152 devices. If i did the request to /redfish/v1/systems only show 500 devices to see other devices i need use skip or expand, but that querys parameters doesnt work.

i have tried this /redfish/v1/systems/?$skip=1150

Can't use logout functionality, return 405 method not allowed but curl commands work fine.

Connecting to the redfish client using the parameter max_retry=2 will cause the client to fail to logout. Tried across different version's and machines all seem to fail once max_retry is used, and once it's removed it will work again.

Example of error message.

 connection = connect(url=url, username=username, password=password, default_prefix=prefix, max_retry=10)
 connection.logout()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/cfm/pyvenvs/cfm/lib/python2.7/site-packages/redfish/rest/v1.py", line 946, in logout
    "return code: %d" % (session_loc, resp.status))
BadRequestError: Invalid session resource: redfish/v1/SessionService/Sessions/<num>/, return code: 405

connect code:

def connect(url, username, password, default_prefix, max_retry=10):
    try:
        connection = redfish.redfish_client(base_url=url, username=username, password=password,
                                            default_prefix=default_prefix, max_retry=max_retry)
        connection.login(auth="session")
    except Exception as e:
        raise RedfishConnectException('nothing important'.format())

    return connection

Unable to upload certificate file

Below is the command which we have to upload the certificate file. Here we have -T option for providing certificate file.

curl -c cjar -b cjar -k -H "X-Auth-Token: $bmc_token" -H "Content-Type: application/octet-stream" -X POST -T <certificate_file_path> https://${BMC_IP}/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates

We have tried to upload certificate file in below manner but its not working and we are getting "Invalid certificate file" in BMC's journal logs.

payload = {"data": <certificate_content>}
response = REDFISH_OBJ.post("BMC_IP}/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates", body=payload)

Please let us know if our approach is correct or not. If not, what is the correct way to upload a file using redfish python library?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.