Message Boards Message Boards

GROUPS:

CloudDeploy with a Package. ExternalBundle?

Posted 5 years ago
6148 Views
|
8 Replies
|
1 Total Likes
|

I want to be able to load a package that I've uploaded to my Cloud account. I'm not sure how to do it, but the usual way to load a package doesn't seem to work. I see that there is a cloud-related function called ExternalBundle. Is that used to include a package? I can't find any examples of how ExternalBundle is used. Anyone know of one?

Ken Levasseur UMass Lowell

8 Replies
Posted 3 years ago

Just starting up on the various cloud functions, and trying to get my mind around them. I am making the transition from webMathematica (JSP, etc.) over to trying out the suite of Cloud functions. I think that I have figured out that CloudDeploy[ ] makes a static definition in that, if I update functions in packages, those updated function don't propagate through to CloudDeploy[ ]. That is a lot different from desktop Mathematica. I have learned instead that I have to execute CloudDeploy again to get the updated functions incorporated into the deployed behavior. In any case, I have learned. Please do correct me if I am missing something on this point (<-there is a question buried in there).

So why am I replying to this discussion: Chad Knutson's post was VERY INFORMATIVE to me. Nevertheless, I didn't really like that it was loading a package without Needs[ ] and mixing the package loading with the function definition. So, below I am posting an alternative format that accomplishes nothing different from Chad Knutson's post but it does do it in a different format. Namely, it separates the package from the API function. Maybe others would find this format helpful, too, so I am posting. Here follows:

Make the package:

BeginPackage["myCloudPackage`"]
myFunc::usage = "Random number generator"
Begin["`Private`"]
myFunc[] := RandomReal[]
End[]
EndPackage[]

Copy over file:

CopyFile["myCloudPackage.m", CloudObject["myCloudPackage.m"]]

Convince you that no cheating is involved so now start with blank slate:

Quit[]

Deploy to the cloud in the alternative format that separates package declaration from function content:

api =

 CloudEvaluate[

  CompoundExpression[
   Needs["myCloudPackage`", "myCloudPackage.m"],
   CloudDeploy[APIFunction[{}, myCloudPackage`myFunc[] &]]
   ]

  ]

Check out the results:

{URLExecute[api], URLExecute[api]}

An interesting question (to me) is why the following code actually does not work since the context is getting updated in the cloud. The fact that it does not work is revealing/instructive about how the suite of Cloud functions differs from interactions with the usual desktop Mathematica:

api =

 CloudEvaluate[

  CompoundExpression[
   Needs["myCloudPackage`", "myCloudPackage.m"],
   AppendTo[$ContextPath, "myCloudPackage`"],
   CloudDeploy[APIFunction[{}, myFunc[] &]]
   ]

  ]

I think the answer lies in Chad Knutson's comment about the 'parser' but there does not seem to be any information on this in the documentation. Any further information on how to deal with Contexts, Packages, or storing user information between interactions for say 30 min (beyond FormFunction[ ] and FormPage[ ]) would be valuable to me (<-there's another question buried in there).

Thank you for reading my post and I hope you found a nugget of something interesting to you.

Great, thanks. I wanted to make sure that there wasn't any subtlety that I was not aware of.

David, yes, I use Unprotect and Protect out of habit. The kernel should not have any user definitions when the APIFunction is evaluated.

Thanks Chad.

Just out of curiosity is there a particular reason for the Unprotect and Protect in the package? Or is that just your approach to package layout?

One reason why I can see why it might be desirable is in case the running Kernel on the cloud has a prior definition of the functions in the package. But I would assume that each time the API is called it runs on what is effectively a fresh Kernel.

Apologies for the long delay in responding. The challenge with loading packages in the cloud is that the parser has to read the function name before the package is loaded. To make this work, you have to provide the context for the function.

Here is a simple example. First my package, saved as "myCloudPackage.m":

BeginPackage["myCloudPackage`"]
Unprotect[myFunc];
myFunc::usage="simple cloud function";
Begin["`Private`"]
myFunc[x_] := 1+x
End[]
Protect[myFunc];
EndPackage[]

I then upload the file to the cloud:

CopyFile["myCloudPackage.m", CloudObject["myCloudPackage.m"]]

Now I can deploy an APIFunction to use the package. Note that I'm using the full context of myFunc.

api = CloudDeploy[
  APIFunction[{"x" -> "Number"}, 
   CloudGet[CloudObject["myCloudPackage.m"]]; 
   myCloudPackage`myFunc[#x] &]]

Finally evaluate in Mathematica:

In[227]:= URLExecute[api, {"x" -> 3}]

Out[227]= "4"

David, WordData is not an external library that one needs to load to use: Mathematica loads its content as needed whenever WordData is called.

Thus if you execute

func = APIFunction[{"str" -> "String"}, WordData[#str] &];

and then deploy it with

CloudDeploy[func]

you will get an API which will call WordData as needed and generate the expected output. For example executing the resulting API with the word "happy" gives this:

enter image description here

Ken, I haven't answered your question here. I haven't yet tried to make use of a package via a cloud account. I will experiment, but perhaps a more knowledgeable person will have a quick answer for you.

I am also wondering this. I want to use WordData in a cloud deployed API. However, it doesn't say in the examples how to load any libraries or resources.

One clarification. I put the package in the Applications folder of my cloud storage and can evaluate it with "less than less than"package name` in another Notebook in my cloud. That works fine. What I can't seem to do is use the package in an expression that I CloudDeploy.

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract