Re: Simple webserver

2023-10-18 Thread Janis Papanagnou via Python-list
On 19.10.2023 01:23, Chris Angelico wrote:
> [snip]
> 
> Hope that's enough to get you started! I'd be delighted to help
> further if you run into difficulties.

Thanks for your quick reply, Chris! This is already great information!
I'll dive into your resources soon, and I also appreciate your offer
and will probably come back soon with a question... - Thanks again!

Janis

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any possible type alias that can also set a default value for a function arg?

2023-10-18 Thread Chris Angelico via Python-list
On Thu, 19 Oct 2023 at 10:11, Matthew Carruth via Python-list
 wrote:
>
> We have the `Optional[T]` type as a short-hand for Union[T | None] and 
> telling us that said argument may not be present.
>
> However, I find that a majority of the time, we also want to set a default 
> value of None on the argument so that it can be evaluated without doing a 
> getattr() check first.
>
> iow, a lot of `foo: Optional[str] = None` in method signatures.
>
> I'd love to see a companion to the Optional type, I'll call it Default, so 
> that it can take a default value as a second arg, with a default of that 
> being None.
>
> For example:
>
> foo: Default[str] would be equivalent to foo: Optional[str] = None
> foo: Default[str, "bar"] would be equivalent to foo: Optional[str] = "bar"
>
> or something like that. Basically, any way to avoid writing `= None` over and 
> over again.

Fundamentally no, at least not without some shenanigans. Type hints do
not affect the regular running of the code, so they can't add
defaults. You could do it the other way around and have the default
imply that it is optional, and I believe that used to be the way that
MyPy calculated things, but it was ultimately rejected. (I may have
the details wrong on that though, don't quote me.)

Ahh, but shenanigans? What kind of shenanigans is that? Glad you
asked! So, uhh, you could decorate a function and mess with its
defaults.

>>> from typing import Optional
>>> def spam(n: Optional[int]):
... if n is None: print("Default spamminess")
... else: print("Spam " * n)
...
>>> spam(5)
Spam Spam Spam Spam Spam
>>> spam(None)
Default spamminess
>>> spam()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: spam() missing 1 required positional argument: 'n'
>>> spam.__defaults__ = (None,)
>>> spam()
Default spamminess

So you could design a decorator that goes through all the arguments,
finds the ones that say "Optional", and adds a default of None if one
wasn't specified. Good luck with it though. First, you'll have to deal
with the difficulties of aligning arguments (not insurmountable but a
lot of work; don't forget that there are posonly and kwonly args to
consider). Then, you'll have to deal with the much bigger difficulties
of convincing people that this is a good thing.

BTW, rather than a decorator, you could do this by iterating over
every function in a module or class. That might work out easier. Not
sure.

Just be aware that, while Python provides you with all the tools
necessary to shoot yourself in the foot, that isn't a guarantee that
holes in feet are worthwhile.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Simple webserver

2023-10-18 Thread Chris Angelico via Python-list
On Thu, 19 Oct 2023 at 10:07, Janis Papanagnou via Python-list
 wrote:
>
> I am pondering about writing a client/server software with
> websockets as communication protocol. The clients will run
> in browser as Javascript programs and the server may be in
> any (any sensible) programming language running standalone
> to be connected remotely by the browser-based JS clients.
>
> I found a Python sample[*] but I am neither familiar with
> Python nor with the 'simple_websocket_server' package that
> is used in that sample code. But the code looks so simple
> that I'm considering to learn and use Python for the task.
>
> The requirements I have are quite simple; I want to get the
> client "address"/identifier from an incoming message, store
> it in a list, and send responses to all active clients for
> which addresses have been stored.
>
> Can anyone tell me whether a simple extension of that "echo
> incoming message" sample[*] would be easily possible with
> Python and with that 'simple_websocket_server' package used?
>
> Thanks for any hints (or search keywords, or code samples)!

Oooh you've touched on one of my favourite topics. I *love* networking
and communication, and websockets are one of my well-used
technologies. Let's do this!!

I've never used the "simple_websocket_server" you mentioned, but I've
used this one in a few projects:

https://pypi.org/project/websockets/

Be aware that it is designed with asyncio in mind, so if you prefer
different concurrency models, you may need to look elsewhere. But I've
had good success with this one.

Broadly speaking, your ideas are great. Any programming language CAN
be used for the server (and I've used several, not just Python).

My personal preference is to build a protocol on top of websockets, for example:

* All messages are "text", and are JSON-encoded
* All messages represent objects (in Python, dictionaries) with a
"cmd" attribute
* The first message sent by the client has cmd "init" and specifies a
"type" and "group".
* The server tracks all connected clients by their groups, and can
broadcast messages to everyone in a group.

Here's one example, actually one of my brother's projects but I
contributed to the websocket aspects:

https://github.com/stephenangelico/BioBox/blob/master/browser.py

And here's one that doesn't actually use Python, but uses all the same
ideas; this is the JS end:

https://github.com/Rosuav/StilleBot/blob/master/httpstatic/ws_sync.js

(It has quite a bit more sophistication than you'll need to get
started with, but shows how the protocol can expand as needed.)

So! Tying this back in with your goals:

> The requirements I have are quite simple; I want to get the
> client "address"/identifier from an incoming message, store
> it in a list, and send responses to all active clients for
> which addresses have been stored.

Sounds to me like the best way would be for the socket group to be the
identifier of the client. You could augment the "init" message to
include some sort of authentication, or alternatively, rely on other
forms of authentication; a websocket established to the same origin as
the page itself can take advantage of regular browser credentials.

Once that's established, you can have a message from one client result
in the server sending out that message to all clients for the
recipient's address.

The reason I'm talking about "groups" here instead of simply having
one client per address is that it scales well to one person having
multiple tabs open, or having the app on their phone as well as their
computer, or anything like that. Messages will arrive on all of them.

Hope that's enough to get you started! I'd be delighted to help
further if you run into difficulties.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Any possible type alias that can also set a default value for a function arg?

2023-10-18 Thread Matthew Carruth via Python-list
We have the `Optional[T]` type as a short-hand for Union[T | None] and telling 
us that said argument may not be present.

However, I find that a majority of the time, we also want to set a default 
value of None on the argument so that it can be evaluated without doing a 
getattr() check first.

iow, a lot of `foo: Optional[str] = None` in method signatures.

I'd love to see a companion to the Optional type, I'll call it Default, so that 
it can take a default value as a second arg, with a default of that being None. 

For example:

foo: Default[str] would be equivalent to foo: Optional[str] = None
foo: Default[str, "bar"] would be equivalent to foo: Optional[str] = "bar"

or something like that. Basically, any way to avoid writing `= None` over and 
over again.
-- 
https://mail.python.org/mailman/listinfo/python-list


Simple webserver

2023-10-18 Thread Janis Papanagnou via Python-list
I am pondering about writing a client/server software with
websockets as communication protocol. The clients will run
in browser as Javascript programs and the server may be in
any (any sensible) programming language running standalone
to be connected remotely by the browser-based JS clients.

I found a Python sample[*] but I am neither familiar with
Python nor with the 'simple_websocket_server' package that
is used in that sample code. But the code looks so simple
that I'm considering to learn and use Python for the task.

The requirements I have are quite simple; I want to get the
client "address"/identifier from an incoming message, store
it in a list, and send responses to all active clients for
which addresses have been stored.

Can anyone tell me whether a simple extension of that "echo
incoming message" sample[*] would be easily possible with
Python and with that 'simple_websocket_server' package used?

Thanks for any hints (or search keywords, or code samples)!

Janis

[*] https://pypi.org/project/simple-websocket-server/
-- 
https://mail.python.org/mailman/listinfo/python-list