Code Monkey home page Code Monkey logo

devtools-proxy's Introduction

DevTools Proxy

Build Status PyPI GitHub release

DevTools Proxy is a tool for creating simultaneous connections via DevTools Protocol (which is not possible by default and it is possible since Chrome 63 even without DevTools Proxy).

How it works

+---+      +---+
| C |      |   |
| L |      | D |    +-----------+
| I |      | E |    |           |
| E |<---->| V |    |  BROWSER  |
| N |      | T |    |           |
| T |      | O |    |           |
+---+      | O |    |   +---+   |
           | L |    |   | T |   |
           | S |<-----> | A |   |
+---+      |   |    |   | B |   |
| C |      | P |    |   +---+   |
| L |      | R |    |           |
| I |<---->| O |    |           |
| E |      | X |    |           |
| N |      | Y |    +-----------+
| T |      |   |
+---+      +---+

Installation

  • Download & unzip standalone binary for your system.
  • If you use Python (at least 3.6) you can install it via pip: pip install devtools-proxy

Usage

With Selenium and ChromeDriver

There are examples for Python and Ruby. Demos for CPU Throttling, Network requests and Remote debugging.

Standalone (for any language)

  • Configure ChromeOptions:
    • Set path to chrome-wrapper.sh as a binary. Optional arguments are mentioned in example for Python below
    • Add --devtools-proxy-binary=/path/to/devtools-proxy to args

Python

devtools-proxy pypi package supports at least Python 3.6. If you use lower Python version use Standalone package.

pip install -U devtools-proxy
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

from devtools.proxy import CHROME_WRAPPER_PATH

devtools_proxy_binary = 'devtools-proxy' # Or path to `devtools-proxy` from downloaded binaries

capabilities = DesiredCapabilities.CHROME.copy()
capabilities['chromeOptions'] = {
    'binary': CHROME_WRAPPER_PATH, # Or path to `chrome-wrapper.sh` from downloaded binaries
    'args': [
        f'--devtools-proxy-binary={devtools_proxy_binary}',
        # Optional arguments:
        # '--chrome-binary=/path/to/chrome/binary', # Path to real Chrome/Chromium binary
        # '--devtools-proxy-chrome-debugging-port=some-free-port', # Port which proxy will listen. Default is 12222
        # '--devtools-proxy-args=--additional --devtools-proxy --arguments, # Additional arguments for devtools-proxy from `devtools-proxy --help`
    ],
}

With multiple Devtools instances

  • Run devtools-proxy (by default it started on 9222 port)
  • Run Chrome with parameters --remote-debugging-port=12222 --remote-debugging-address=127.0.0.1
  • Open a website which you want to inspect
  • Open debugger in a new Chrome tab: http://localhost:9222 and choose your website to inspect
  • Repeat the previous step as many times as you need it

devtools-proxy's People

Contributors

bayandin avatar pyup-bot 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

Watchers

 avatar  avatar  avatar  avatar  avatar

devtools-proxy's Issues

Unable to switch to iframe

I am unable to switch context to iframe elements while using devtools-proxy. The same code works without using the proxy. Any ideas why this might be happening?

Sample code:

devtools_proxy_port = 9222
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--start-maximized')
chrome_options.add_argument('--ignore-certificate-errors')
chrome_options.add_argument('--disable-application-cache')
chrome_options.add_argument('--no-sandbox')
chrome_options.binary_location = CHROME_WRAPPER_PATH

chrome_options.add_argument('--chrome-binary=' + binary_location)
chrome_options.add_argument('--devtools-proxy-binary=devtools-proxy')
chrome_options.add_argument(f'--devtools-proxy-args=--port {devtools_proxy_port}')
driver = webdriver.Chrome(driver_path, chrome_options=chrome_options)

driver.set_page_load_timeout(page_load_timeout)


 try:
    driver.get('http://www.' + url_link)
    devtools_client.main_func(url_link)

    iframe_elements = driver.find_elements_by_tag_name('iframe')
    driver.switch_to.frame(iframe_elements[0])
    # Also tried with index, id but no luck
    # driver.switch_to.frame(0)
    # driver.switch_to.frame('iframe_id')
 except Exception as e:
    print('something went wrong.')

I am using Selenium 3.6, ChromeDriver 2.21, and Chromium. 48.

Windows support

On my current project I need to run devtools-proxy in Windows 10. As I understand now it's impossible to do this. Am I right? If yes, do I need to write dev-tools.bat the same manner as .sh or it requires additional changed in library?

Unable to start chrome using devtools-proxy

I'm trying to use devtools-proxy, but when using it chrome won't start. I've got Selenium 3.6.0 installed. I installed devtools-proxy through pip3.

$ sudo -H pip3 install devtools-proxy
Collecting devtools-proxy
  Downloading devtools_proxy-0.0.6-py3-none-any.whl
Collecting cchardet==1.1.1 (from devtools-proxy)
  Downloading cchardet-1.1.1.tar.gz (620kB)
    100% |████████████████████████████████| 624kB 1.7MB/s
Requirement already satisfied: ujson==1.35 in /usr/local/lib/python3.6/site-packages (from devtools-proxy)
Collecting uvloop==0.6.7 (from devtools-proxy)
  Downloading uvloop-0.6.7.tar.gz (1.7MB)
    100% |████████████████████████████████| 1.7MB 898kB/s
Collecting aiohttp==1.1.6 (from devtools-proxy)
  Downloading aiohttp-1.1.6.tar.gz (510kB)
    100% |████████████████████████████████| 512kB 2.6MB/s
Requirement already satisfied: chardet in /usr/local/lib/python3.6/site-packages (from aiohttp==1.1.6->devtools-proxy)
Requirement already satisfied: multidict>=2.0 in /usr/local/lib/python3.6/site-packages (from aiohttp==1.1.6->devtools-proxy)
Requirement already satisfied: async_timeout>=1.1.0 in /usr/local/lib/python3.6/site-packages (from aiohttp==1.1.6->devtools-proxy)
Requirement already satisfied: yarl>=0.5.0 in /usr/local/lib/python3.6/site-packages (from aiohttp==1.1.6->devtools-proxy)
Building wheels for collected packages: cchardet, uvloop, aiohttp
  Running setup.py bdist_wheel for cchardet ... done
  Stored in directory: /var/root/Library/Caches/pip/wheels/52/56/8e/6f1ebbce9f28bf511170c925b594c525c9ea398a7809a9eb8b
  Running setup.py bdist_wheel for uvloop ... done
  Stored in directory: /var/root/Library/Caches/pip/wheels/32/fd/98/363c2fb841a9814d3c80a9b4a5c8cd7e31615b317708dc399a
  Running setup.py bdist_wheel for aiohttp ... done
  Stored in directory: /var/root/Library/Caches/pip/wheels/7f/4e/fc/6a1b28666e2a8626948c14ef0838584faa63aa0a0c90a6d92c
Successfully built cchardet uvloop aiohttp
Installing collected packages: cchardet, uvloop, aiohttp, devtools-proxy
  Found existing installation: cchardet 2.1.1
    Uninstalling cchardet-2.1.1:
      Successfully uninstalled cchardet-2.1.1
  Found existing installation: uvloop 0.8.1
    Uninstalling uvloop-0.8.1:
      Successfully uninstalled uvloop-0.8.1
  Found existing installation: aiohttp 2.2.5
    Uninstalling aiohttp-2.2.5:
      Successfully uninstalled aiohttp-2.2.5
Successfully installed aiohttp-1.1.6 cchardet-1.1.1 devtools-proxy-0.0.6 uvloop-0.6.7

When I run your throttling.py example, I get the following output from the console.

$ python3 test.py
Traceback (most recent call last):
  File "test.py", line 23, in <module>
    driver = selenium.webdriver.Chrome(desired_capabilities=desired_capabilities)
  File "/usr/local/lib/python3.6/site-packages/selenium/webdriver/chrome/webdriver.py", line 69, in __init__
    desired_capabilities=desired_capabilities)
  File "/usr/local/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 151, in __init__
    self.start_session(desired_capabilities, browser_profile)
  File "/usr/local/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 240, in start_session
    response = self.execute(Command.NEW_SESSION, parameters)
  File "/usr/local/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 308, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally
  (Driver info: chromedriver=2.32.498537 (cb2f855cbc7b82e20387eaf9a43f6b99b6105061),platform=Mac OS X 10.12.6 x86_64)

I tried installing devtools-proxy from source, but it ran into problems during compilation and had a segfault.

$ python3 setup.py install
/usr/local/lib/python3.6/site-packages/setuptools/dist.py:351: UserWarning: Normalizing '0.1.0-dev' to '0.1.0.dev0'
  normalized_version,
running install
running bdist_egg
running egg_info
creating devtools_proxy.egg-info
writing devtools_proxy.egg-info/PKG-INFO
writing dependency_links to devtools_proxy.egg-info/dependency_links.txt
writing entry points to devtools_proxy.egg-info/entry_points.txt
writing requirements to devtools_proxy.egg-info/requires.txt
writing top-level names to devtools_proxy.egg-info/top_level.txt
writing manifest file 'devtools_proxy.egg-info/SOURCES.txt'
reading manifest file 'devtools_proxy.egg-info/SOURCES.txt'
writing manifest file 'devtools_proxy.egg-info/SOURCES.txt'
installing library code to build/bdist.macosx-10.12-x86_64/egg
running install_lib
running build_py
creating build/bdist.macosx-10.12-x86_64
creating build/bdist.macosx-10.12-x86_64/egg
creating build/bdist.macosx-10.12-x86_64/egg/devtools
copying build/lib/devtools/__init__.py -> build/bdist.macosx-10.12-x86_64/egg/devtools
copying build/lib/devtools/chrome-wrapper.sh -> build/bdist.macosx-10.12-x86_64/egg/devtools
copying build/lib/devtools/proxy.py -> build/bdist.macosx-10.12-x86_64/egg/devtools
byte-compiling build/bdist.macosx-10.12-x86_64/egg/devtools/__init__.py to __init__.cpython-36.pyc
byte-compiling build/bdist.macosx-10.12-x86_64/egg/devtools/proxy.py to proxy.cpython-36.pyc
creating build/bdist.macosx-10.12-x86_64/egg/EGG-INFO
copying devtools_proxy.egg-info/PKG-INFO -> build/bdist.macosx-10.12-x86_64/egg/EGG-INFO
copying devtools_proxy.egg-info/SOURCES.txt -> build/bdist.macosx-10.12-x86_64/egg/EGG-INFO
copying devtools_proxy.egg-info/dependency_links.txt -> build/bdist.macosx-10.12-x86_64/egg/EGG-INFO
copying devtools_proxy.egg-info/entry_points.txt -> build/bdist.macosx-10.12-x86_64/egg/EGG-INFO
copying devtools_proxy.egg-info/requires.txt -> build/bdist.macosx-10.12-x86_64/egg/EGG-INFO
copying devtools_proxy.egg-info/top_level.txt -> build/bdist.macosx-10.12-x86_64/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
devtools.__pycache__.proxy.cpython-36: module references __file__
creating dist
creating 'dist/devtools_proxy-0.1.0.dev0-py3.6.egg' and adding 'build/bdist.macosx-10.12-x86_64/egg' to it
removing 'build/bdist.macosx-10.12-x86_64/egg' (and everything under it)
Processing devtools_proxy-0.1.0.dev0-py3.6.egg
creating /usr/local/lib/python3.6/site-packages/devtools_proxy-0.1.0.dev0-py3.6.egg
Extracting devtools_proxy-0.1.0.dev0-py3.6.egg to /usr/local/lib/python3.6/site-packages
Adding devtools-proxy 0.1.0.dev0 to easy-install.pth file
Installing devtools-proxy script to /usr/local/bin

Installed /usr/local/lib/python3.6/site-packages/devtools_proxy-0.1.0.dev0-py3.6.egg
Processing dependencies for devtools-proxy==0.1.0.dev0
Searching for uvloop==0.8.1
Reading https://pypi.python.org/simple/uvloop/
Downloading https://pypi.python.org/packages/8a/90/2ee7d33ed33cdd493f1f2e78ca2c3cb7823e2dceb875ac52e7096d4f6004/uvloop-0.8.1.tar.gz#md5=74e24dfee440468fd580b2020c28fc75
Best match: uvloop 0.8.1
Processing uvloop-0.8.1.tar.gz
Writing /var/folders/4z/tglhq8852976mz3lzqkmtn1w0000gn/T/easy_install-c6cptxo_/uvloop-0.8.1/setup.cfg
Running uvloop-0.8.1/setup.py -q bdist_egg --dist-dir /var/folders/4z/tglhq8852976mz3lzqkmtn1w0000gn/T/easy_install-c6cptxo_/uvloop-0.8.1/egg-dist-tmp-5z6nqukc
warning: no previously-included files matching '*' found under directory 'vendor/libuv/.git'
warning: no previously-included files matching '*' found under directory 'vendor/libuv/docs'
warning: no previously-included files matching '*' found under directory 'vendor/libuv/img'
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... ./install-sh -c -d
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking build system type... x86_64-apple-darwin16.7.0
checking host system type... x86_64-apple-darwin16.7.0
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking if gcc supports -pedantic flag... yes
checking for gcc way to treat warnings as errors... -Werror
checking if gcc supports -fvisibility=hidden... yes
checking if gcc supports -g flag... yes
checking if gcc supports -std=gnu89 flag... yes
checking if gcc supports -Wall flag... yes
checking if gcc supports -Wextra flag... yes
checking if gcc supports -Wno-unused-parameter flag... yes
checking for ar... ar
checking the archiver (ar) interface... ar
checking how to print strings... printf
checking for a sed that does not truncate output... /usr/bin/sed
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for fgrep... /usr/bin/grep -F
checking for ld used by gcc... /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld
checking if the linker (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld) is GNU ld... no
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 196608
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking how to convert x86_64-apple-darwin16.7.0 file names to x86_64-apple-darwin16.7.0 format... func_convert_file_noop
checking how to convert x86_64-apple-darwin16.7.0 file names to toolchain format... func_convert_file_noop
checking for /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for archiver @FILE support... no
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from gcc object... ok
checking for sysroot... no
checking for mt... no
checking if : is a manifest tool... no
checking for dsymutil... dsymutil
checking for nmedit... nmedit
checking for lipo... lipo
checking for otool... otool
checking for otool64... no
checking for -single_module linker flag... yes
checking for -exported_symbols_list linker flag... yes
checking for -force_load linker flag... yes
checking how to run the C preprocessor... gcc -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if gcc supports -fno-rtti -fno-exceptions... yes
checking for gcc option to produce PIC... -fno-common -DPIC
checking if gcc PIC flag -fno-common -DPIC works... yes
checking if gcc static flag -static works... no
checking if gcc supports -c -o file.o... yes
checking if gcc supports -c -o file.o... (cached) yes
checking whether the gcc linker (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld) supports shared libraries... yes
checking dynamic linker characteristics... darwin16.7.0 dyld
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
checking whether make supports nested variables... (cached) yes
checking for dlopen in -ldl... yes
checking for kstat_lookup in -lkstat... no
checking for kvm_open in -lkvm... no
checking for gethostbyname in -lnsl... no
checking for perfstat_cpu in -lperfstat... no
checking for pthread_mutex_init in -lpthread... yes
checking for clock_gettime in -lrt... no
checking for sendfile in -lsendfile... no
checking for socket in -lsocket... no
checking for special C compiler options needed for large files... no
checking for _FILE_OFFSET_BITS value needed for large files... no
checking sys/ahafs_evProds.h usability... no
checking sys/ahafs_evProds.h presence... no
checking for sys/ahafs_evProds.h... no
checking for pkg-config... yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating libuv.pc
config.status: creating Makefile
config.status: executing depfiles commands
config.status: executing libtool commands
  CC       src/libuv_la-fs-poll.lo
  CC       src/libuv_la-threadpool.lo
  CC       src/libuv_la-inet.lo
  CC       src/libuv_la-uv-common.lo
  CC       src/libuv_la-version.lo
  CC       src/unix/libuv_la-async.lo
  CC       src/unix/libuv_la-core.lo
  CC       src/unix/libuv_la-dl.lo
  CC       src/unix/libuv_la-fs.lo
  CC       src/unix/libuv_la-getaddrinfo.lo
  CC       src/unix/libuv_la-getnameinfo.lo
  CC       src/unix/libuv_la-loop-watcher.lo
  CC       src/unix/libuv_la-loop.lo
  CC       src/unix/libuv_la-pipe.lo
  CC       src/unix/libuv_la-poll.lo
  CC       src/unix/libuv_la-process.lo
  CC       src/unix/libuv_la-signal.lo
  CC       src/unix/libuv_la-stream.lo
  CC       src/unix/libuv_la-tcp.lo
  CC       src/unix/libuv_la-thread.lo
  CC       src/unix/libuv_la-timer.lo
  CC       src/unix/libuv_la-tty.lo
  CC       src/unix/libuv_la-udp.lo
  CC       src/unix/libuv_la-darwin.lo
  CC       src/unix/libuv_la-darwin-proctitle.lo
  CC       src/unix/libuv_la-fsevents.lo
  CC       src/unix/libuv_la-kqueue.lo
  CC       src/unix/libuv_la-proctitle.lo
  CC       src/unix/libuv_la-pthread-barrier.lo
  CCLD     libuv.la
In file included from uvloop/loop.c:450:
uvloop/includes/compat.h:28:69: warning: control reaches end of non-void function [-Wreturn-type]
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) {};
                                                                    ^
uvloop/loop.c:69240:34: warning: comparison of unsigned expression < 0 is always false [-Wtautological-compare]
      __pyx_t_2 = ((__pyx_v_sent < 0) != 0);
                    ~~~~~~~~~~~~ ^ ~
uvloop/loop.c:87164:15: warning: code will never be executed [-Wunreachable-code]
              goto __pyx_L24;
              ^~~~~~~~~~~~~~
uvloop/loop.c:133958:93: warning: code will never be executed [-Wunreachable-code]
        module = PyImport_ImportModule((PY_VERSION_HEX >= 0x03030000) ? "collections.abc" : "collections");
                                                                                            ^~~~~~~~~~~~~
uvloop/loop.c:133958:59: note: silence by adding parentheses to mark code as explicitly dead
        module = PyImport_ImportModule((PY_VERSION_HEX >= 0x03030000) ? "collections.abc" : "collections");
                                                          ^
                                                          /* DISABLES CODE */ ( )
4 warnings generated.
zip_safe flag not set; analyzing archive contents...
uvloop.__pycache__.loop.cpython-36: module references __file__
creating /usr/local/lib/python3.6/site-packages/uvloop-0.8.1-py3.6-macosx-10.12-x86_64.egg
Extracting uvloop-0.8.1-py3.6-macosx-10.12-x86_64.egg to /usr/local/lib/python3.6/site-packages
Adding uvloop 0.8.1 to easy-install.pth file

Installed /usr/local/lib/python3.6/site-packages/uvloop-0.8.1-py3.6-macosx-10.12-x86_64.egg
Searching for cchardet==2.1.1
Reading https://pypi.python.org/simple/cchardet/
Downloading https://pypi.python.org/packages/63/74/fbf92cd7fe2e603600096098d78f5c5957c5071861298d00084f058e174f/cchardet-2.1.1.tar.gz#md5=bbfb26239b5129e93c8812efcc54d935
Best match: cchardet 2.1.1
Processing cchardet-2.1.1.tar.gz
Writing /var/folders/4z/tglhq8852976mz3lzqkmtn1w0000gn/T/easy_install-4nxkofch/cchardet-2.1.1/setup.cfg
Running cchardet-2.1.1/setup.py -q bdist_egg --dist-dir /var/folders/4z/tglhq8852976mz3lzqkmtn1w0000gn/T/easy_install-4nxkofch/cchardet-2.1.1/egg-dist-tmp-ei_p3ao4
cythonize: ['src/cchardet/_cchardet.pyx']
Segmentation fault: 11

How can I get this working?

Thank you!

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.