def serialize_v2_event(event): """Serialize a Thrift struct to bytes for the V2 event protocol. :param event: A Thrift struct from the event schemas. """ return Serializer.serialize(_V2_PROTOCOL_FACTORY, event)
def serialize_thrift_object(thrift_obj, proto_factory=Consts.PROTO_FACTORY): ''' Serialize thrift data to binary blob :param thrift_obj: the thrift object :param proto_factory: protocol factory, set default as Compact Protocol :return: string the serialized thrift payload ''' return Serializer.serialize(proto_factory(), thrift_obj)
def write_empty_dir(self, inode_number: int) -> None: from thrift.util import Serializer from thrift.protocol import TCompactProtocol empty_tree = OverlayDir() protocol_factory = TCompactProtocol.TCompactProtocolFactory() contents = typing.cast( bytes, Serializer.serialize(protocol_factory, empty_tree)) self._write_inode(inode_number, OverlayHeader.TYPE_DIR, contents)
def test_exception_safety(self) -> None: for protocol in PROTOCOLS: with self.subTest(protocol=type(protocol).__name__): foo = Foo(structField={}) with patch( "thrift.test.py.adapter_for_tests.AdapterTestStructToDict.to_thrift" ) as mock_to_thrift, self.assertRaises(RuntimeError): mock_to_thrift.side_effect = RuntimeError() Serializer.serialize(protocol, foo) serialized = Serializer.serialize( protocol, FooWithoutAdapters(structField=Bar()), ) with patch( "thrift.test.py.adapter_for_tests.AdapterTestStructToDict.from_thrift" ) as mock_from_thrift, self.assertRaises(RuntimeError): mock_from_thrift.side_effect = RuntimeError() Serializer.deserialize(protocol, serialized, Foo())
def do_stats_general(instance: EdenInstance, options: StatsGeneralOptions) -> None: out, basic, json = options with instance.get_thrift_client_legacy(timeout=20) as client: statsMask = STATS_MOUNTS_STATS | STATS_RSS_BYTES if basic else STATS_ALL stat_info = client.getStatInfo(GetStatInfoParams(statsMask=statsMask)) if json: json_factory = TSimpleJSONProtocolFactory() out.write( ThriftSerializer.serialize(json_factory, stat_info).decode("utf-8")) else: print_stats(stat_info, out)
def test_roundtrip(self) -> None: INPUTS = { "empty": (Foo(), FooWithoutAdapters()), "default_values": ( Foo( structField={}, oStructField={}, mapField={}, ), FooWithoutAdapters( structField=Bar(), oStructField=Bar(), mapField={}, ), ), "basic": ( Foo( structField={"field": 42}, oStructField={"field": 43}, mapField={ 1: { "field": 44 }, 2: { "field": 45 }, }, ), FooWithoutAdapters( structField=Bar(field=42), oStructField=Bar(field=43), mapField={ 1: Bar(field=44), 2: Bar(field=45), }, ), ), } for protocol in PROTOCOLS: for (name, (foo, foo_without_adapters)) in INPUTS.items(): with self.subTest(case=name, protocol=type(protocol).__name__): serialized = Serializer.serialize(protocol, foo) deserialized = Serializer.deserialize( protocol, serialized, Foo()) self.assertEqual(deserialized, foo) no_adapter = Serializer.deserialize( protocol, serialized, FooWithoutAdapters()) self.assertEqual(no_adapter, foo_without_adapters)
def create(cls, authentication_context=None, loid_id=None, loid_created_ms=None, session_id=None): """Factory method to create a new EdgeRequestContext object. Builds a new EdgeRequestContext object with the given parameters and serializes the "Edge-Request" header. :param baseplate.core.AuthenticationContext authentication_context: (Optional) AuthenticationContext for the current request if it is authenticated. :param str loid_id: (Optional) ID for the current LoID in fullname format. :param int loid_created_ms: (Optional) Epoch milliseconds when the current LoID cookie was created. :param str session_id: (Optional) ID for the current session cookie. """ # Importing the Thrift models inline so that building them is not a # hard, import-time dependency for tasks like building the docs. from .thrift.ttypes import Loid as TLoid from .thrift.ttypes import Request as TRequest from .thrift.ttypes import Session as TSession if loid_id is not None and not loid_id.startswith("t2_"): raise ValueError( "loid_id <%s> is not in a valid format, it should be in the " "fullname format with the '0' padding removed: 't2_loid_id'", loid_id) loid = TLoid(id=loid_id, created_ms=loid_created_ms) session = TSession(id=session_id) request = TRequest(loid=loid, session=session) header = Serializer.serialize(cls._HEADER_PROTOCOL_FACTORY, request) if authentication_context is None: authentication_context = AuthenticationContext() request_context = cls(header, authentication_context) # Set the _t_request property so we can skip the deserialization step # since we already have the thrift object. request_context._t_request = request return request_context
def _serialize(self, obj): return Serializer.serialize(self.protocol_factory, obj)
def run(self, args: argparse.Namespace) -> int: if args.list: self._list_functions() return 0 if not args.function_name: print(f"Error: no function name specified", file=sys.stderr) print( "Use the --list argument to see a list of available functions, or " "specify a function name", file=sys.stderr, ) return 1 # Look up the function information try: fn_info = thrift.util.inspect.get_function_info( EdenService, args.function_name) except thrift.util.inspect.NoSuchFunctionError: print(f"Error: unknown function {args.function_name!r}", file=sys.stderr) print( 'Run "eden debug thrift --list" to see a list of available functions', file=sys.stderr, ) return 1 if len(args.args) != len(fn_info.arg_specs): print( f"Error: {args.function_name} requires {len(fn_info.arg_specs)} " f"arguments, but {len(args.args)} were supplied>", file=sys.stderr, ) return 1 python_args = self._eval_args(args.args, fn_info, eval_strings=args.eval_all_args) def lookup_module_member(modules, name): for module in modules: try: return getattr(module, name) except AttributeError: continue raise AttributeError(f"Failed to find {name} in {modules}") instance = cmd_util.get_eden_instance(args) with instance.get_thrift_client() as client: fn = getattr(client, args.function_name) result = fn(**python_args) if args.json: # The following back-and-forth is required to reliably # convert a Python Thrift client result into its JSON # form. The Python Thrift client returns native Python # lists and dicts for lists and maps, but they cannot # be passed directly to TSimpleJSONProtocol. Instead, # map the result back into a Thrift message, and then # serialize that as JSON. Finally, strip the message # container. # # NOTE: Stripping the root object means the output may # not have a root dict or array, which is required by # most JSON specs. But Python's json module and jq are # both fine with this deviation. result_type = lookup_module_member( [EdenService, BaseService], args.function_name + "_result") json_data = Serializer.serialize(TSimpleJSONProtocolFactory(), result_type(result)) json.dump( # If the method returns void, json_data will not # have a "success" field. Print `null` in that # case. json.loads(json_data).get("success"), sys.stdout, sort_keys=True, indent=2, ) sys.stdout.write("\n") else: print(result) return 0
def _serialize(self, obj): return Serializer.serialize(self.serialize_factory, obj)
def new(self, authentication_token=None, loid_id=None, loid_created_ms=None, session_id=None): """Return a new EdgeRequestContext object made from scratch. Services at the edge that communicate directly with clients should use this to pass on the information they get to downstream services. They can then use this information to check authentication, run experiments, etc. To use this, create and attach the context early in your request flow: .. code-block:: python auth_cookie = request.cookies["authentication"] token = request.authentication_service.authenticate_cookie(cookie) loid = parse_loid(request.cookies["loid"]) session = parse_session(request.cookies["session"]) edge_context = self.edgecontext_factory.new( authentication_token=token, loid_id=loid.id, loid_created_ms=loid.created, session_id=session.id, ) edge_context.attach_context(request) :param authentication_token: (Optional) A raw authentication token as returned by the authentication service. :param str loid_id: (Optional) ID for the current LoID in fullname format. :param int loid_created_ms: (Optional) Epoch milliseconds when the current LoID cookie was created. :param str session_id: (Optional) ID for the current session cookie. """ # Importing the Thrift models inline so that building them is not a # hard, import-time dependency for tasks like building the docs. from .thrift.ttypes import Loid as TLoid from .thrift.ttypes import Request as TRequest from .thrift.ttypes import Session as TSession if loid_id is not None and not loid_id.startswith("t2_"): raise ValueError( "loid_id <%s> is not in a valid format, it should be in the " "fullname format with the '0' padding removed: 't2_loid_id'", loid_id) t_request = TRequest( loid=TLoid(id=loid_id, created_ms=loid_created_ms), session=TSession(id=session_id), authentication_token=authentication_token, ) header = Serializer.serialize( EdgeRequestContext._HEADER_PROTOCOL_FACTORY, t_request) context = EdgeRequestContext(self.authn_token_validator, header) # Set the _t_request property so we can skip the deserialization step # since we already have the thrift object. context._t_request = t_request return context
def testNestedStructs(self): self._deserialize(NestedStructs, '{"1":{"rec":{}}"2":{"rec":{}}}') self._deserialize(NestedStructs, '{"1":{"rec":{}},"2":{"rec":{}}}') nested = NestedStructs(bonk=Bonk(), bools=Bools()) protocol_factory = TJSONProtocol.TJSONProtocolFactory(validJSON=True) json.loads(Serializer.serialize(protocol_factory, nested))
def writeToJSON(obj): return Serializer.serialize(NomadJSONProtocolFactory(), obj)