Skip to content
This repository has been archived by the owner on Mar 8, 2020. It is now read-only.

Commit

Permalink
Merge pull request #1 from vmarkovtsev/master
Browse files Browse the repository at this point in the history
Add the initial module
  • Loading branch information
smola authored Jun 15, 2017
2 parents cf0a9b2 + 3c42cb1 commit 0e8ca2e
Show file tree
Hide file tree
Showing 27 changed files with 3,184 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.idea

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
19 changes: 19 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
language: python
sudo: false
services:
- docker
cache:
directories:
- $HOME/.cache/pip
python:
- "3.4"
- "3.5"
- "3.6"
install:
- pip install --upgrade pip
- pip install grpcio
- CC=gcc-5 CXX=g++-5 pip install -e .
script:
- python3 -m unittest discover .
notifications:
email: false
35 changes: 35 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
PYTHON ?= python3

makefile_dir := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

all: bblfsh/github/com/gogo/protobuf/gogoproto/gogo_pb2.py \
bblfsh/github/com/bblfsh/sdk/uast/generated_pb2.py \
bblfsh/github/com/bblfsh/sdk/protocol/generated_pb2_*.py \
bblfsh/github/__init__.py \
bblfsh/github/com/__init__.py \
bblfsh/github/com/gogo/__init__.py \
bblfsh/github/com/gogo/protobuf/__init__.py \
bblfsh/github/com/gogo/protobuf/gogoproto/__init__.py \
bblfsh/github/com/bblfsh/__init__.py \
bblfsh/github/com/bblfsh/sdk/__init__.py \
bblfsh/github/com/bblfsh/sdk/uast/__init__.py \
bblfsh/github/com/bblfsh/sdk/protocol/__init__.py

bblfsh/github/com/gogo/protobuf/gogoproto/gogo_pb2.py: github.com/gogo/protobuf/gogoproto/gogo.proto
protoc --python_out bblfsh github.com/gogo/protobuf/gogoproto/gogo.proto

bblfsh/github/com/bblfsh/sdk/uast/generated_pb2.py: github.com/bblfsh/sdk/uast/generated.proto
protoc --python_out bblfsh github.com/bblfsh/sdk/uast/generated.proto

bblfsh/github/com/bblfsh/sdk/protocol:
@mkdir -p $@

bblfsh/github/com/bblfsh/sdk/protocol/generated_pb2_*.py: \
bblfsh/github/com/bblfsh/sdk/protocol github.com/bblfsh/sdk/protocol/generated.proto
$(PYTHON) -m grpc.tools.protoc --python_out=bblfsh/github/com/bblfsh/sdk/protocol \
--grpc_python_out=bblfsh/github/com/bblfsh/sdk/protocol \
-I github.com/bblfsh/sdk/protocol -I $(makefile_dir) \
github.com/bblfsh/sdk/protocol/generated.proto

%/__init__.py:
@touch $@
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
## Babelfish Python client

This a pure Python implementation of querying [Babelfish](https://doc.bblf.sh/) server.

### Usage

API
```
from bblfsh import BblfshClient
client = BblfshClient("0.0.0.0:9432")
print(client.parse_uast("/path/to/file.py"))
```

Command line
```
python3 -m bblfsh -f file.py
```

### Installation

```
pip3 install bblfsh
```

It is possible to regenerate the gRPC/protobuf bindings by executing `make`.

### License

Apache 2.0.
1 change: 1 addition & 0 deletions bblfsh/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from bblfsh.client import BblfshClient
34 changes: 34 additions & 0 deletions bblfsh/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import argparse
import sys

from bblfsh.client import BblfshClient
from bblfsh.launcher import ensure_bblfsh_is_running


def setup():
parser = argparse.ArgumentParser(
description="Query for a UAST to Babelfish and dump it to stdout."
)
parser.add_argument("-e", "--endpoint", default="0.0.0.0:9432",
help="bblfsh gRPC endpoint.")
parser.add_argument("-f", "--file", required=True,
help="File to parse.")
parser.add_argument("-l", "--language", default=None,
help="File's language. The default is to autodetect.")
parser.add_argument("--disable-bblfsh-autorun", action="store_true",
help="Do not automatically launch Babelfish server "
"if it is not running.")
args = parser.parse_args()
return args


def main():
args = setup()
if not args.disable_bblfsh_autorun:
ensure_bblfsh_is_running()
client = BblfshClient(args.endpoint)
print(client.parse_uast(args.file, args.language))


if __name__ == "__main__":
sys.exit(main())
64 changes: 64 additions & 0 deletions bblfsh/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import os
import sys

import grpc

# The following two insertions fix the broken pb import paths
sys.path.insert(0, os.path.join(os.path.dirname(__file__),
"github/com/bblfsh/sdk/protocol"))
sys.path.insert(0, os.path.dirname(__file__))
from bblfsh.github.com.bblfsh.sdk.protocol.generated_pb2 import ParseUASTRequest
from bblfsh.github.com.bblfsh.sdk.protocol.generated_pb2_grpc import ProtocolServiceStub


class BblfshClient(object):
"""
Babelfish gRPC client. Currently it is only capable of fetching UASTs.
"""

def __init__(self, endpoint):
"""
Initializes a new instance of BblfshClient.
:param endpoint: The address of the Babelfish server, \
for example "0.0.0.0:9432"
:type endpoint: str
"""
self._channel = grpc.insecure_channel(endpoint)
self._stub = ProtocolServiceStub(self._channel)

def parse_uast(self, filename, language=None, contents=None):
"""
Queries the Babelfish server and receives the UAST for the specified
file.
:param filename: The path to the file. Can be arbitrary if contents \
is not None.
:param language: The programming language of the file. Refer to \
https://doc.bblf.sh/languages.html for the list of \
currently supported languages. None means autodetect.
:param contents: The contents of the file. IF None, it is read from \
filename.
:type filename: str
:type language: str
:type contents: str
:return: UAST object.
"""
if contents is None:
with open(filename) as fin:
contents = fin.read()
request = ParseUASTRequest(filename=os.path.basename(filename),
content=contents,
language=self._scramble_language(language))
response = self._stub.ParseUAST(request)
return response

@staticmethod
def _scramble_language(lang):
if lang is None:
return None
lang = lang.lower()
lang = lang.replace(" ", "-")
lang = lang.replace("+", "p")
lang = lang.replace("#", "sharp")
return lang
Empty file added bblfsh/github/__init__.py
Empty file.
Empty file added bblfsh/github/com/__init__.py
Empty file.
Empty file.
Empty file.
Empty file.
Loading

0 comments on commit 0e8ca2e

Please sign in to comment.