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

Commit 0e8ca2e

Browse files
authored
Merge pull request #1 from vmarkovtsev/master
Add the initial module
2 parents cf0a9b2 + 3c42cb1 commit 0e8ca2e

File tree

27 files changed

+3184
-0
lines changed

27 files changed

+3184
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.idea
2+
13
# Byte-compiled / optimized / DLL files
24
__pycache__/
35
*.py[cod]

.travis.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
language: python
2+
sudo: false
3+
services:
4+
- docker
5+
cache:
6+
directories:
7+
- $HOME/.cache/pip
8+
python:
9+
- "3.4"
10+
- "3.5"
11+
- "3.6"
12+
install:
13+
- pip install --upgrade pip
14+
- pip install grpcio
15+
- CC=gcc-5 CXX=g++-5 pip install -e .
16+
script:
17+
- python3 -m unittest discover .
18+
notifications:
19+
email: false

Makefile

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
PYTHON ?= python3
2+
3+
makefile_dir := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
4+
5+
all: bblfsh/github/com/gogo/protobuf/gogoproto/gogo_pb2.py \
6+
bblfsh/github/com/bblfsh/sdk/uast/generated_pb2.py \
7+
bblfsh/github/com/bblfsh/sdk/protocol/generated_pb2_*.py \
8+
bblfsh/github/__init__.py \
9+
bblfsh/github/com/__init__.py \
10+
bblfsh/github/com/gogo/__init__.py \
11+
bblfsh/github/com/gogo/protobuf/__init__.py \
12+
bblfsh/github/com/gogo/protobuf/gogoproto/__init__.py \
13+
bblfsh/github/com/bblfsh/__init__.py \
14+
bblfsh/github/com/bblfsh/sdk/__init__.py \
15+
bblfsh/github/com/bblfsh/sdk/uast/__init__.py \
16+
bblfsh/github/com/bblfsh/sdk/protocol/__init__.py
17+
18+
bblfsh/github/com/gogo/protobuf/gogoproto/gogo_pb2.py: github.com/gogo/protobuf/gogoproto/gogo.proto
19+
protoc --python_out bblfsh github.com/gogo/protobuf/gogoproto/gogo.proto
20+
21+
bblfsh/github/com/bblfsh/sdk/uast/generated_pb2.py: github.com/bblfsh/sdk/uast/generated.proto
22+
protoc --python_out bblfsh github.com/bblfsh/sdk/uast/generated.proto
23+
24+
bblfsh/github/com/bblfsh/sdk/protocol:
25+
@mkdir -p $@
26+
27+
bblfsh/github/com/bblfsh/sdk/protocol/generated_pb2_*.py: \
28+
bblfsh/github/com/bblfsh/sdk/protocol github.com/bblfsh/sdk/protocol/generated.proto
29+
$(PYTHON) -m grpc.tools.protoc --python_out=bblfsh/github/com/bblfsh/sdk/protocol \
30+
--grpc_python_out=bblfsh/github/com/bblfsh/sdk/protocol \
31+
-I github.com/bblfsh/sdk/protocol -I $(makefile_dir) \
32+
github.com/bblfsh/sdk/protocol/generated.proto
33+
34+
%/__init__.py:
35+
@touch $@

README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
## Babelfish Python client
2+
3+
This a pure Python implementation of querying [Babelfish](https://doc.bblf.sh/) server.
4+
5+
### Usage
6+
7+
API
8+
```
9+
from bblfsh import BblfshClient
10+
11+
client = BblfshClient("0.0.0.0:9432")
12+
print(client.parse_uast("/path/to/file.py"))
13+
```
14+
15+
Command line
16+
```
17+
python3 -m bblfsh -f file.py
18+
```
19+
20+
### Installation
21+
22+
```
23+
pip3 install bblfsh
24+
```
25+
26+
It is possible to regenerate the gRPC/protobuf bindings by executing `make`.
27+
28+
### License
29+
30+
Apache 2.0.

bblfsh/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from bblfsh.client import BblfshClient

bblfsh/__main__.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import argparse
2+
import sys
3+
4+
from bblfsh.client import BblfshClient
5+
from bblfsh.launcher import ensure_bblfsh_is_running
6+
7+
8+
def setup():
9+
parser = argparse.ArgumentParser(
10+
description="Query for a UAST to Babelfish and dump it to stdout."
11+
)
12+
parser.add_argument("-e", "--endpoint", default="0.0.0.0:9432",
13+
help="bblfsh gRPC endpoint.")
14+
parser.add_argument("-f", "--file", required=True,
15+
help="File to parse.")
16+
parser.add_argument("-l", "--language", default=None,
17+
help="File's language. The default is to autodetect.")
18+
parser.add_argument("--disable-bblfsh-autorun", action="store_true",
19+
help="Do not automatically launch Babelfish server "
20+
"if it is not running.")
21+
args = parser.parse_args()
22+
return args
23+
24+
25+
def main():
26+
args = setup()
27+
if not args.disable_bblfsh_autorun:
28+
ensure_bblfsh_is_running()
29+
client = BblfshClient(args.endpoint)
30+
print(client.parse_uast(args.file, args.language))
31+
32+
33+
if __name__ == "__main__":
34+
sys.exit(main())

bblfsh/client.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import os
2+
import sys
3+
4+
import grpc
5+
6+
# The following two insertions fix the broken pb import paths
7+
sys.path.insert(0, os.path.join(os.path.dirname(__file__),
8+
"github/com/bblfsh/sdk/protocol"))
9+
sys.path.insert(0, os.path.dirname(__file__))
10+
from bblfsh.github.com.bblfsh.sdk.protocol.generated_pb2 import ParseUASTRequest
11+
from bblfsh.github.com.bblfsh.sdk.protocol.generated_pb2_grpc import ProtocolServiceStub
12+
13+
14+
class BblfshClient(object):
15+
"""
16+
Babelfish gRPC client. Currently it is only capable of fetching UASTs.
17+
"""
18+
19+
def __init__(self, endpoint):
20+
"""
21+
Initializes a new instance of BblfshClient.
22+
23+
:param endpoint: The address of the Babelfish server, \
24+
for example "0.0.0.0:9432"
25+
:type endpoint: str
26+
"""
27+
self._channel = grpc.insecure_channel(endpoint)
28+
self._stub = ProtocolServiceStub(self._channel)
29+
30+
def parse_uast(self, filename, language=None, contents=None):
31+
"""
32+
Queries the Babelfish server and receives the UAST for the specified
33+
file.
34+
35+
:param filename: The path to the file. Can be arbitrary if contents \
36+
is not None.
37+
:param language: The programming language of the file. Refer to \
38+
https://doc.bblf.sh/languages.html for the list of \
39+
currently supported languages. None means autodetect.
40+
:param contents: The contents of the file. IF None, it is read from \
41+
filename.
42+
:type filename: str
43+
:type language: str
44+
:type contents: str
45+
:return: UAST object.
46+
"""
47+
if contents is None:
48+
with open(filename) as fin:
49+
contents = fin.read()
50+
request = ParseUASTRequest(filename=os.path.basename(filename),
51+
content=contents,
52+
language=self._scramble_language(language))
53+
response = self._stub.ParseUAST(request)
54+
return response
55+
56+
@staticmethod
57+
def _scramble_language(lang):
58+
if lang is None:
59+
return None
60+
lang = lang.lower()
61+
lang = lang.replace(" ", "-")
62+
lang = lang.replace("+", "p")
63+
lang = lang.replace("#", "sharp")
64+
return lang

bblfsh/github/__init__.py

Whitespace-only changes.

bblfsh/github/com/__init__.py

Whitespace-only changes.

bblfsh/github/com/bblfsh/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)