Giter VIP home page Giter VIP logo

lex-bot-tester's Introduction

banner

lex-bot-tester

AWS Lex Bot Tester is a library that simplifies the creation of Amazon Alexa Skills and AWS Lex Bot functional tests.

While this framework has been developed in python (Node version in in the roadmap) it can be used to test Skills and Bots developed in any language.

Using AWS Lex Models Client this utility inspects the properties of the available Bots and creates specific Results classes to be used by the tests.

Certainly, there are ways of testing your bots using AWS CLI as explained in Test the Bot Using Text Input (AWS CLI) but lex-bot-tester provides a more concise, type safe and object oriented way of doing it.

Installation

Run

pip install lex-bot-tester

Examples

Alexa Skill test example

This example uses Alexa Skill Blueprint: BookMyTrip.

Using lex-bot-tester conversational tests like the following one can be created with minimal effort.

class AlexaSkillManagementClientTests(AlexaSkillTest):

    def test_book_my_trip_reserve_a_car(self):
        skill_name = 'BookMyTripSkill'
        intent = 'BookCar'
        conversation = [
            {'slot': None, 'text': 'ask book my trip to reserve a car'},
            {'slot': 'CarType', 'text': 'midsize'},
            {'slot': 'PickUpCity', 'text': 'buenos aires'},
            {'slot': 'PickUpDate', 'text': 'tomorrow'},
            {'slot': 'ReturnDate', 'text': 'five days from now'},
            {'slot': 'DriverAge', 'text': 'twenty five'},
            {'slot': None, 'prompt': 'Confirmation', 'text': 'yes'}
        ]
        self.conversation_text(skill_name, intent, conversation, verbose=True)

you can see full source code at alexaskillmanagementclienttests.py.

Running the tests

You can run the tests from your favorite IDE or from the command line.

If you are interested in seeing the details of the conversation you can add the --verbose option to the test runner.

$ ./alexaskillmamagementclienttests.py --verbose

and you will see an interaction similar to this one

test run

AWS Lex Bot test example

You may be familiar with this kind of tests in the AWS Lex Console (this example uses the well know OrderFlowers bot).

test-bot

More information about these manual tests using the console can be found here

However, once you have the lex-bot-tester installed, you can create tests like this one:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""
    Lex Bot Tester
    Copyright (C) 2017  Diego Torres Milano

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
import re
import unittest

from lex_bot_tester.aws.lex.conversation import Conversation, ConversationItem
from lex_bot_tester.aws.lex.lexbottest import LexBotTest
from lex_bot_tester.aws.lex.lexmodelsclient import LexModelsClient
from lex_bot_tester.aws.lex.lexruntimeclient import DialogState

RE_DATE = re.compile('\d+-\d+-\d+')

BOT_NAME = 'OrderFlowers'
BOT_ALIAS = 'OrderFlowersLatest'
USER_ID = 'ClientId'


class OrderFlowersTests(LexBotTest):
    def test_conversations_text(self):
        lmc = LexModelsClient(BOT_NAME, BOT_ALIAS)
        conversations = []
        for i in lmc.get_intents_for_bot():
            r = lmc.get_result_class_for_intent(i)
            if i == 'OrderFlowers':
                conversations.append(Conversation(
                    ConversationItem('I would like to order some roses',
                                     r(DialogState.ELICIT_SLOT, flower_type='roses')),
                    ConversationItem('white', r(DialogState.ELICIT_SLOT, flower_type='roses', flower_color='white')),
                    ConversationItem('next Sunday',
                                     r(DialogState.ELICIT_SLOT, flower_type='roses', flower_color='white',
                                       pickup_date=RE_DATE)),
                    ConversationItem('noon', r(DialogState.CONFIRM_INTENT, flower_type='roses', flower_color='white',
                                               pickup_date=RE_DATE, pickup_time='12:00')),
                    ConversationItem('yes', r(DialogState.FULFILLED, flower_type='roses', flower_color='white',
                                              pickup_date=RE_DATE, pickup_time='12:00')),
                ))
            elif i == 'Cancel':
                conversations.append(Conversation(
                    ConversationItem('Cancel', r(DialogState.READY_FOR_FULFILLMENT))
                ))
        self.conversations_text(BOT_NAME, BOT_ALIAS, USER_ID, conversations)


if __name__ == '__main__':
    unittest.main()

This test, first creates a LexModelsClient to inspect the definitions of the bot, its intents and slots to later use a class factory that defines specific classes for each intent which are obtained by get_result_class_for_intent(i).

This result class reference, which extends ResultBase class is assigned to the variable r for convenience. Then, for each intent, a Conversation, consisting of a list of ConversationItems is created.

ConversationItem specifies the text or utterance sent and the expected result, using the r class reference and invoking the constructor with the expected DialogState and the values of the slots.

pickup_date is a particular case, as it is selected as next Sunday so instead of looking for a particular value we are checking if it matches a regular expression defining dates.

Finally, once the conversation list is completed, a call to the helper method conversations_text providing this list as an argument completes the test.

However, if you are more into a data-driven approach, you can also declare the conversation as a data structure as shown in the following example.

    def test_conversations_text_book_car(self):
        bot_name = 'BookTrip'
        bot_alias = 'BookTripLatest'
        user_id = 'ClientId'
        conversation_definition = {
            'BookCar': [
                ('book a car', DialogState.ELICIT_SLOT, {}),
                ('L.A.', DialogState.ELICIT_SLOT, {}),
                ('next week', DialogState.ELICIT_SLOT, {'PickUpDate': RE_WEEK}),
                ('a month from now', DialogState.ELICIT_SLOT, {'ReturnDate': RE_DATE}),
                ('25', DialogState.ELICIT_SLOT, {}),
                ('economy', DialogState.CONFIRM_INTENT, {}),
                ('yes', DialogState.READY_FOR_FULFILLMENT, {}),
            ],
            'Cancel': [
                ('cancel', DialogState.READY_FOR_FULFILLMENT, {})
            ]
        }
        self.conversations_text_helper(bot_alias, bot_name, user_id, conversation_definition, verbose)

Both approaches are identical in functionality, so you can choose the one that suits your taste.

Result classes

As mentioned before, LexModelsClient.get_result_class_for_intent(intent) returns the class that represents the response result once the Bot is invoked using the corresponding utterance.

The signature of the constructor matches this pattern

class MyIntentResult(ResultBase):
    def __init__(dialog_state, **kwargs):
        ...

To comply with PEP 8, keyword args representing slots are named using snake case when usually slots are named using camel case. Then, for example, the slot FlowerType will be represented by its corresponding keyword arg flower_type.

Conversations

Conversation is a list of ConversationItems. These ConversationItems represent the send -> response interaction.

class ConversationItem(object):
    
    def __init__(self, send, receive):
        ...

Perhaps, taking a look at lexbottestertests.py clarifies the idea. That test, uses the same structure and the classes created by inspecting the models for two different Bots: OrderFlowers and BookTrip.

Running the tests

You can run the tests from your favorite IDE or from the command line.

If you are interested in seeing the details of the conversation you can add the --verbose option to the test runner.

$ ./lexbottesttests.py --verbose

and you will see an interaction similar to the one presented before.

term-output

Resources

lex-bot-tester's People

Contributors

dtmilano avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar

lex-bot-tester's Issues

No Module

No module named lex_bot_tester.aws.alexa.alexaskillmanagementclient

pip install fails

Excited to use the application! Unfortunately pip install lex-bot-tester fails. Looks like it fails when trying to uninstall the dateutil package. I've attached the log. Errors start in the bolded section.
Any ideas?


Collecting lex-bot-tester
Using cached lex_bot_tester-1.0.4-py2.py3-none-any.whl
Requirement already satisfied: requests in /Library/Python/2.7/site-packages (from lex-bot-tester)
Requirement already satisfied: six in /Library/Python/2.7/site-packages/six-1.10.0-py2.7.egg (from lex-bot-tester)
Requirement already satisfied: setuptools in /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python (from lex-bot-tester)
Collecting boto3 (from lex-bot-tester)
Using cached boto3-1.6.3-py2.py3-none-any.whl
Requirement already satisfied: urllib3<1.23,>=1.21.1 in /Library/Python/2.7/site-packages (from requests->lex-bot-tester)
Requirement already satisfied: idna<2.7,>=2.5 in /Library/Python/2.7/site-packages (from requests->lex-bot-tester)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /Library/Python/2.7/site-packages (from requests->lex-bot-tester)
Requirement already satisfied: certifi>=2017.4.17 in /Library/Python/2.7/site-packages (from requests->lex-bot-tester)
Requirement already satisfied: jmespath<1.0.0,>=0.7.1 in /Library/Python/2.7/site-packages (from boto3->lex-bot-tester)
Requirement already satisfied: s3transfer<0.2.0,>=0.1.10 in /Library/Python/2.7/site-packages (from boto3->lex-bot-tester)
Collecting botocore<1.10.0,>=1.9.3 (from boto3->lex-bot-tester)
Using cached botocore-1.9.3-py2.py3-none-any.whl
Requirement already satisfied: futures<4.0.0,>=2.2.0; python_version == "2.6" or python_version == "2.7" in /Library/Python/2.7/site-packages (from s3transfer<0.2.0,>=0.1.10->boto3->lex-bot-tester)
Collecting python-dateutil<3.0.0,>=2.1 (from botocore<1.10.0,>=1.9.3->boto3->lex-bot-tester)
Using cached python_dateutil-2.6.1-py2.py3-none-any.whl
Requirement already satisfied: docutils>=0.10 in /Library/Python/2.7/site-packages (from botocore<1.10.0,>=1.9.3->boto3->lex-bot-tester)

Installing collected packages: python-dateutil, botocore, boto3, lex-bot-tester
Found existing installation: python-dateutil 1.5
Uninstalling python-dateutil-1.5:
Exception:
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/pip/basecommand.py", line 215, in main
status = self.run(options, args)
File "/Library/Python/2.7/site-packages/pip/commands/install.py", line 342, in run
prefix=options.prefix_path,
File "/Library/Python/2.7/site-packages/pip/req/req_set.py", line 778, in install
requirement.uninstall(auto_confirm=True)
File "/Library/Python/2.7/site-packages/pip/req/req_install.py", line 754, in uninstall
paths_to_remove.remove(auto_confirm)
File "/Library/Python/2.7/site-packages/pip/req/req_uninstall.py", line 115, in remove
renames(path, new_path)
File "/Library/Python/2.7/site-packages/pip/utils/init.py", line 267, in renames
shutil.move(old, new)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 299, in move
copytree(src, real_dst, symlinks=True)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 208, in copytree
raise Error, errors

Error: [('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/init.py', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/init.py', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/init.py'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/init.pyc', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/init.pyc', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/init.pyc'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/easter.py', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/easter.py', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/easter.py'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/easter.pyc', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/easter.pyc', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/easter.pyc'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/parser.py', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/parser.py', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/parser.py'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/parser.pyc', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/parser.pyc', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/parser.pyc'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/relativedelta.py', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/relativedelta.py', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/relativedelta.py'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/relativedelta.pyc', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/relativedelta.pyc', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/relativedelta.pyc'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/rrule.py', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/rrule.py', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/rrule.py'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/rrule.pyc', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/rrule.pyc', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/rrule.pyc'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/tz.py', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/tz.py', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/tz.py'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/tz.pyc', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/tz.pyc', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/tz.pyc'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/tzwin.py', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/tzwin.py', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/tzwin.py'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/tzwin.pyc', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/tzwin.pyc', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/tzwin.pyc'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/zoneinfo/init.py', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/zoneinfo/init.py', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/zoneinfo/init.py'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/zoneinfo/init.pyc', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/zoneinfo/init.pyc', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/zoneinfo/init.pyc'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/zoneinfo/zoneinfo-2010g.tar.gz', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/zoneinfo/zoneinfo-2010g.tar.gz', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/zoneinfo/zoneinfo-2010g.tar.gz'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/zoneinfo', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/zoneinfo', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/zoneinfo'"), ('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil', '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil', "[Errno 1] Operation not permitted: '/var/folders/jy/xdv7r06s2hx87htlp70l3xt87vnqcz/T/pip-zdvoYu-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil'")]

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.