[Pythonmac-SIG] PyObjC and Criollo HTTP server

Rand Dvorak randdvorak at gmail.com
Wed Jan 8 15:55:34 EST 2020


Here’s what I’ve got so far.   I don’t know much about the metadata, but I did try gen_bridge_metadata to try and decipher it, but I think it doesn’t generate it correctly either.

import objc 
CRApplication = objc.lookUpClass("CRApplication")
objc.registerMetaDataForSelector(
	b'CRHTTPServer',
	b'get:block:',
	{
	'arguments': {
		3: { 'callable': {
			'arguments': {
			0:{'type': b'^v'},
			1:{'type': b'@'},
			2:{'type': b'@'},
			3:{'type': b'@'}
			},
		'	retval': { 'type': b'v' }
			}
		   }
		}
	}
)

global server

	
def helloHandler(request, response, handler):
	response.send_("Hello World!")
	handler()
	
if __name__ == "__main__":
	server = CRApplication.sharedApplication().delegate().server()
	server.get_block_("/", helloHandler)
	server.startListening()


> On Jan 8, 2020, at 15:41, Ronald Oussoren <ronaldoussoren at mac.com> wrote:
> 
> What is the type of ‘server’?
> 
> And I just noticed the metadata block is a bit of, the callable is argument 3 instead of 2. 
> 
> Ronald
> 
> --
> On the road, hence brief. 
> 
>> On 8 Jan 2020, at 17:18, Rand Dvorak <randdvorak at gmail.com> wrote:
>> 
>> Same result:
>> 
>>   File "main.py", line 40, in <module>
>>     server.get_block_("/", helloHandler)
>> TypeError: Argument 3 is a block, but no signature available
>> 
>> 
>>> On Jan 8, 2020, at 03:20, Ronald Oussoren <ronaldoussoren at mac.com <mailto:ronaldoussoren at mac.com>> wrote:
>>> 
>>> Please change “get_block_” to “get:block:” in the call to objc.registerMetadataForSelector.
>>> 
>>> Ronald
>>>>>> 
>>> Twitter: @ronaldoussoren
>>> Blog: https://blog.ronaldoussoren.net/ <https://blog.ronaldoussoren.net/>
>>> 
>>>> On 8 Jan 2020, at 02:04, Rand Dvorak <randdvorak at gmail.com <mailto:randdvorak at gmail.com>> wrote:
>>>> 
>>>> Same results with this code:
>>>> 
>>>> import objc 
>>>> CRApplication = objc.lookUpClass("CRApplication")
>>>> objc.registerMetaDataForSelector(
>>>> 	b'CRServer',
>>>> 	b'get_block_',
>>>> 	{
>>>> 	'arguments': {
>>>> 		2: {
>>>> 			'callable': {
>>>> 			'arguments': {
>>>> 			0:{'type': b'^v'},
>>>> 			1:{'type': b'@'},
>>>> 			2:{'type': b'@'},
>>>> 			3:{'type': b'?'}
>>>> 			},
>>>> 		'	retval': { 'type': b'v' }
>>>> 			} 
>>>> 		}
>>>> 	}
>>>> 	}
>>>> )
>>>> 
>>>> global server
>>>> 
>>>> 	
>>>> def helloHandler(request, response, handler):
>>>> 	response.send_("Hello World!")
>>>> 	handler()
>>>> 	
>>>> if __name__ == "__main__":
>>>> 	server = CRApplication.sharedApplication().delegate().server()
>>>> 	server.get_block_("/", helloHandler)
>>>> 	server.startListening()
>>>> 
>>>> 
>>>>> On Jan 7, 2020, at 04:47, Ronald Oussoren <ronaldoussoren at mac.com <mailto:ronaldoussoren at mac.com>> wrote:
>>>>> 
>>>>> And given de example on https://criollo.io: <https://criollo.io/>
>>>>> 
>>>>> - The class name is CRServer, not CRApplication
>>>>> - The selector is “get:block:” instead of “get_block:”, which also means the block is argument 3 instead of 2.
>>>>> 
>>>>>>> objc.registerMetaDataForSelector(
>>>>>>> 	b'CRServer',
>>>>>>> 	b’get:block:',
>>>>>>> 	{
>>>>>>> 	'arguments': {
>>>>>>> 		3: {
>>>>>>> 			'callable': {
>>>>>>> 			'arguments': {
>>>>>>> 			0:{'type': b'^v'},
>>>>>>> 			1:{'type': b'@'},
>>>>>>> 			2:{'type': b'@'},
>>>>>>> 			3:{'type': b'@'}
>>>>>>> 			},
>>>>>>> 			'retval': { 'type': b'v' }
>>>>>>> 			} 
>>>>>>> 		}
>>>>>>> 	}
>>>>>>> 	}
>>>>>>> )
>>>>> 
>>>>> and later:
>>>>> 
>>>>>>> 	server.get_block_("/", helloHandler)
>>>>> 
>>>>>> 
>>>>> 
>>>>> 
>>>>>>>>>> 
>>>>> Twitter: @ronaldoussoren
>>>>> Blog: https://blog.ronaldoussoren.net/ <https://blog.ronaldoussoren.net/>
>>>>> 
>>>>>> On 7 Jan 2020, at 10:00, Ronald Oussoren via Pythonmac-SIG <pythonmac-sig at python.org <mailto:pythonmac-sig at python.org>> wrote:
>>>>>> 
>>>>>> Hi,
>>>>>> 
>>>>>> You also need to remove the call to objc.selector. With correct metadata “blocks” are callables in Python code.
>>>>>> 
>>>>>> Ronald
>>>>>>>>>>>> 
>>>>>> Twitter: @ronaldoussoren
>>>>>> Blog: https://blog.ronaldoussoren.net/ <https://blog.ronaldoussoren.net/>
>>>>>> 
>>>>>>> On 6 Jan 2020, at 23:59, Rand Dvorak <randdvorak at gmail.com <mailto:randdvorak at gmail.com>> wrote:
>>>>>>> 
>>>>>>> Same result:
>>>>>>> 
>>>>>>> Updated code:
>>>>>>> 
>>>>>>> import objc 
>>>>>>> CRApplication = objc.lookUpClass("CRApplication")
>>>>>>> objc.registerMetaDataForSelector(
>>>>>>> 	b'CRApplication',
>>>>>>> 	b'get_block_',
>>>>>>> 	{
>>>>>>> 	'arguments': {
>>>>>>> 		2: {
>>>>>>> 			'callable': {
>>>>>>> 			'arguments': {
>>>>>>> 			0:{'type': b'^v'},
>>>>>>> 			1:{'type': b'@'},
>>>>>>> 			2:{'type': b'@'},
>>>>>>> 			3:{'type': b'@'}
>>>>>>> 			},
>>>>>>> 		'	retval': { 'type': b'v' }
>>>>>>> 			} 
>>>>>>> 		}
>>>>>>> 	}
>>>>>>> 	}
>>>>>>> )
>>>>>>> global server
>>>>>>> 
>>>>>>> def helloHandler(self, request, response, handler):
>>>>>>> 	response.send_("Hello World!")
>>>>>>> 	handler()
>>>>>>> 	
>>>>>>> if __name__ == "__main__":
>>>>>>> 	server = CRApplication.sharedApplication().delegate().server()
>>>>>>> 	server.get_block_("/", objc.selector(helloHandler, signature=b'v@:@@@'))
>>>>>>> 	server.startListening()
>>>>>>> 
>>>>>>> 
>>>>>>> results:
>>>>>>> 
>>>>>>> Traceback (most recent call last):
>>>>>>>   File "main.py", line 37, in <module>
>>>>>>>     server.get_block_("/", objc.selector(helloHandler, signature=b'v@:@@@'))
>>>>>>> TypeError: Argument 3 is a block, but no signature available
>>>>>>> 
>>>>>>> 
>>>>>>>> On Jan 6, 2020, at 09:27, Ronald Oussoren <ronaldoussoren at mac.com <mailto:ronaldoussoren at mac.com>> wrote:
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>>> On 6 Jan 2020, at 00:51, Rand Dvorak <randdvorak at gmail.com <mailto:randdvorak at gmail.com>> wrote:
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> I am trying to implement a simple server in PyObjC for the Criollo HTTP server.  The server has a method to set route handlers by passing a block to setup the route and then when it receives and HTTP request for the route it calls the block.  The block has the signature:
>>>>>>>>> 
>>>>>>>>> typedef void(^CRRouteBlock)(CRRequest* _Nonnull request, CRResponse* _Nonnull response, CRRouteCompletionBlock _Nonnull completionHandler);
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> So, here is my simple proof of concept:
>>>>>>>>> 
>>>>>>>>> import objc 
>>>>>>>>> CRApplication = objc.lookUpClass("CRApplication")
>>>>>>>>> global server
>>>>>>>>> 
>>>>>>>>> def helloHandler(self, request, response, handler):
>>>>>>>>> 	response.send_("Hello World!")
>>>>>>>>> 	handler()
>>>>>>>>> 	
>>>>>>>>> if __name__ == "__main__":
>>>>>>>>> 	server = CRApplication.sharedApplication().delegate().server()
>>>>>>>>> 	server.get_block_("/", objc.selector(helloHandler, signature=b'v@:@@@‘))  *** error occurs here
>>>>>>>>> 	server.startListening()
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> But, when I try to setup the route I get the following error:
>>>>>>>>> 
>>>>>>>>> Traceback (most recent call last):
>>>>>>>>> File "main.py", line 21, in <module>
>>>>>>>>>   server.get_block_("/", objc.selector(helloHandler, signature=b'v@:@@'))
>>>>>>>>> TypeError: Argument 3 is a block, but no signature available
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> Any ideas how to workaround this issue and implement the route handlers in PyObjC?
>>>>>>>> 
>>>>>>>> The code below should do the trick, but eas typed directly into this mail and might therefore contain syntax errors.
>>>>>>>> 
>>>>>>>> import objc
>>>>>>>> objc.registerMetaDataForSelector(
>>>>>>>>    b”CRApplication”,  # name of the class implementing “get_block:”, or “NSObject”
>>>>>>>>    b”get_block:”,
>>>>>>>>   {
>>>>>>>>     “arguments”: {
>>>>>>>>       2: {
>>>>>>>>         “callable”: {
>>>>>>>>          “arguments”: {
>>>>>>>>           0: { “type”: b”^v” },
>>>>>>>>           1: { “type”: b”@” },
>>>>>>>>           2: { “type”: b”@” },
>>>>>>>>           3: { “type”: b”@” }
>>>>>>>>          },
>>>>>>>>          “retail”: { “type”: b”v” }
>>>>>>>>        } 
>>>>>>>>      }
>>>>>>>>   }
>>>>>>>> )
>>>>>>>> 
>>>>>>>> This tells the bridge the signature for the block argument of the “get_block:” selector, which is information that cannot be retrieved from the Objective-C runtime.  Argument 2 is the first real argument of ObjC selectors, after the implicit arguments “self” and “_imp” (which is not available in python code).
>>>>>>>> 
>>>>>>>> Ronald
>>>>>>>>>>>>>>>> 
>>>>>>>> Twitter: @ronaldoussoren
>>>>>>>> Blog: https://blog.ronaldoussoren.net/ <https://blog.ronaldoussoren.net/>
>>>>>>>>> _______________________________________________
>>>>>>>>> Pythonmac-SIG maillist  -  Pythonmac-SIG at python.org <mailto:Pythonmac-SIG at python.org>
>>>>>>>>> https://mail.python.org/mailman/listinfo/pythonmac-sig <https://mail.python.org/mailman/listinfo/pythonmac-sig>
>>>>>>>>> unsubscribe: https://mail.python.org/mailman/options/Pythonmac-SIG <https://mail.python.org/mailman/options/Pythonmac-SIG>
>>>>>>>> 
>>>>>>> 
>>>>>> 
>>>>>> _______________________________________________
>>>>>> Pythonmac-SIG maillist  -  Pythonmac-SIG at python.org <mailto:Pythonmac-SIG at python.org>
>>>>>> https://mail.python.org/mailman/listinfo/pythonmac-sig <https://mail.python.org/mailman/listinfo/pythonmac-sig>
>>>>>> unsubscribe: https://mail.python.org/mailman/options/Pythonmac-SIG <https://mail.python.org/mailman/options/Pythonmac-SIG>
>>>>> 
>>>> 
>>> 
>> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/pythonmac-sig/attachments/20200108/5769da20/attachment-0001.html>


More information about the Pythonmac-SIG mailing list