New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Default namespace not being used #233
Comments
Hello, First, thank you for your detailed report and constructive approach. Let's look at this one by one:
All this said, here's how I'll close this issue report:
Anything to add? Best regards, |
FYI, This is how your test case fails now:
|
(note to self: do not reply to github issues with email.) On Wed, 2013-05-29 at 08:54 -0700, Burak Arslan wrote:
Fair enough.
I am not familiar enough with SOAP or XML name spaces to understand this completely. So lets say we have:
I presume the issue is that you need to generate unique XML names for these two Foo's, so you generate these targetNamespace's:
and this thus two Foo's end up with XML different names. Having now read a bit about XML namespaces, my_package.x1 isn't a very good XML namespace name. Namespaces are generally URL's. URL's have the nice property of being guaranteed to be unique. These generated generated ones have much less chance of being unique. Still, the generated namespace names do serve a purpose. I take it they are required so you have to have something, and they are unique within the application which is all that matters. Or at least I assume those So lets look at two use cases. The first one is I do care about the namespace used. In this case explicitly setting Still, being able to define a unique prefix for every namespace sounds like a nice short cut. If I could pass something like tns_prefix="http://my.domain.com/path/program" to Application(), and then have Foo() class above generate a namespace like "http://my.domain.com/path/program.my_package.x1" I could use your The second use case is the Python programmer doesn't care about namespaces. I suspect this is the normal case. In that case you solution of just using the unadorned module name is fine, as you just need something unique with the application. In Python, the main program does have a name, "main". It is unique. Why not use it? The programmer by definition doesn't care what name you use, just as long at it works. It will work, won't it?
You can't wriggle out of it that easily. I write doco too. Here is an example: http://www.stuart.id.au/russell/files/lrparsing/doc/html So I am fully aware of how much effort it takes. On Wed, 2013-05-29 at 09:05 -0700, Burak Arslan wrote:
A definite improvement. As a programmer, on seeing that error my first step would be to go searching for |
(github's email parsing used to be way better!) On 05/30/13 04:22, rstuart wrote:
Correct. As you say, If you care about the namespaces you expose, you should set them as proper uris. If not, the generated ones are not that good, but the best we can do.
You can set a default namespace, see the last example before Array here: http://spyne.io/docs/2.10/manual/03_types.html#complex
Yes I could, but that's not really what is done in the XML world. People either don't care about namespaces or want to have very strict control over them. Also;
So, no, that's not going to happen. That behaviour is pretty much set in stone now.
Well... yes, it'll work. My arguments here are nothing more than "it's ugly" and "it's not a real namespace". Ok, I agree that the average python programmer shouldn't have to learn all this. Initally at least. Especially if (s)he's not evaluating Spyne for a non-xml protocol. I'll just replace
But I wasn't trying to! Here's what happened though: I thought having a docstring for Here's the docstring: https://github.com/arskom/spyne/blob/master/spyne/model/_base.py#L101 I'm just saying that I need an outsider's perspective on making this more clear. So assuming I put And hey, thanks a lot for your time. |
Hmm. Looks like I have an admission to make. When I started I was using 2.9, as that was what I could find packaged for Debian. So I read it's manual. I have since packaged 2.10.7 for Debian, but haven't re-read the 2.10.7 manual. I thought it would be much the same, but no, you are obviously working hard on it. That chapter on types didn't exist in 2.9. Actually, I noticed you mentioned ordering in that type chapter. I wondered about that. Again I don't know much about SOAP, but SOAP calling its structures a "sequence" suggests the declared order is important. Which is an issue, because I can tell you from experience the order a dict is traversed is unpredictable. And I know in the metaclass you will be grabbing those field declarations from the passed dict, in the order some iterator returns them to you. This ordering can change between versions of Python. It has done so. Code I wrote persisted a dict to disk and compared the string it wrote to the current version to check if something had changed. After an upgrade it all broke even though the dict itself was identical. I also know that in C# and Java, they grab the WSDL and compile it, so if ordering is important and it changes bad things will happen. In theory this is easily solved, you just ensure every field constructor involves a call of some kind, you never allow:
and always insist on:
The call can then increment a global counter and store it in the type definition, and then you can use that counter to figure out the order the fields were declared in the class body. Of course "easy" is a relative term, and it means breaking the API, particularly for ComplexModel where the constructor currently instantiates an object, not a type.
That would solve my main whinge completely.
Ahh, OK.
If I have a minor complaint about the wording I put in a pull request. It was a little hard to put in a pull request when the scaffolding wasn't there. |
apology accepted ;) don't hesitate to tell me if you figure anthing else is missing.
Wow, you're good :) In the Python 2.x world, changing Python versions is not that frequent nowadays. But the dict order gets shuffled when one adds a new field to an object as well. Contrary to what it seems, this is not guaranteed to be a backwards-compatible change (even when that field's an optional one) as schema validation (that's not a SOAP thing, but an Xml Schema thing) validates order of the elements as well. (Soft validation does not mind) So if your client(s) have your old WSDL cached, some requests will start failing for no apparent reason upon next deployment. Whether you care or not depends mostly on the type of clients you serve though, so I don't want to make the lives of people who don't care about argument order harder for no apparent benefit to them.
This is a respectable idea which I'm not so sure initially about how it'd pan out, but would you mind not diverting much from the subject at hand? There is going to be a Python-3-only Spyne 3 (I can't wait to lay my hands on function annotations :)) and I intend to have an open discussion about what to change. |
So ok, conclusion:
Anything else to add? |
Nope. So many words from me for such a little change. Sorry - I'll leave you in peace now. |
So, now default ns is always used whenever an explicit ns is missing. Re-open if you have anything else to say. I'll happily discuss it :) |
Especially regarding the docs! |
Consider this python program:
Running it produces:
Which is because in the generated tns.xsd
xmlns:s0=""
appears at line 1, column 269 (column 73 in the above error message is wrong):The temporary directory spyne created (in my case
/tmp/spynevMB5tX
) wasn't cleaned up. That happened to be helpful for writing up the issue, but leaving junk lying around like that won't make me friends with my sysadmin. I guess it was deliberate, otherwise you just would have usedlxml.etree.fromstring()
.I also don't know enough about xml, spyne or SOAP to say whether producing an invalid WSDL like that is a reasonable thing to do, but it sure is annoying. As a suggestion, when no namespace is selected it would be real nice if you just used the default namespace passed to
spyne.application.Application()
. Or to put it another way, the above program behaved like this one, which does result in every complex type using the default namespace passed toApplication()
:Figuring out this would do what I want took hours of reading the reference doco, and when that didn't help pouring through the source code. Unfortunately it didn't occur to me to look too closely at the examples. If I had, I may have noticed mention of the undocumented
__namespace__
that appears in__namespace__ = 'spyne.examples.user_manager'
. I think assigning something to__namespace__
is currently required to get a workingComplexModel
type, so mentioning that you have to do it in the tutorials and defining what__namespace___
does in the doco would be helpful.Apart from this namespace spyne has been a pleasure to use.
The text was updated successfully, but these errors were encountered: