-
Notifications
You must be signed in to change notification settings - Fork 20
Add the initial module #1
Changes from all commits
d5e370a
ab463ee
a05bcac
cea3a2f
565bf81
b451928
1e394bd
3c42cb1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| .idea | ||
|
|
||
| # Byte-compiled / optimized / DLL files | ||
| __pycache__/ | ||
| *.py[cod] | ||
|
|
||
| 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 |
| 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 $@ | ||
| 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. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| from bblfsh.client import BblfshClient |
| 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()) |
| 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): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should have a method to close the client and the underlying connection.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no close(). Python does it automatically without ResourceWarning-s. Even the Python grpc primer does not close anything: http://www.grpc.io/docs/tutorials/basic/python.html
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
| """ | ||
| 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 | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(non blocking) another option would be to add a first level
__init__with an import hook that knows how to do the rest, but this does the job perfectly too.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is very hacky too.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is but done well it could be more generic/automatic for other use cases of this gRPC module.