Further Reading
The Team Render Sever is an open source plugin written in Python using the Cinema 4D Python SDK and the Flask framework. With a few lines of code a new route is added to do what you need in your workflow.
Basic Functions
You can find the Team Render Sever in resource\modules\teamrender\webserver. Simply open webserver.pyp in an appropriate editor. In the post describing how to create you own front-end you saw that this Flask server presents different access points called “routes”. These routes can be called through the corresponding URL. To add a new route to the server just add a new function definition to the class FlaskServer.
The most simple example would just return a fixed string:
@app.route(register("/helloWorld")) def GetHelloWorld(): return "Hello World!"
The first line registers the new route, so in this case you have to call “http://localhost:8080/helloWorld“. When you call this URL the server will execute the defined function which will return a fixed string.
To send different arguments to the server, the server can handle different parts of the URL as a variable:
@app.route(register("/echo/<text>")) def GetEcho(text): return "Echo:"+text
In this example the second part of the URL defined by <text> will be copied in to a variable of the same name that is available in the corresponding function.
If you want to send a string with special encoding or you want to send confidential information like a password you can define that a route will only respond to POST requests:
@app.route(register("/echoPost"), methods=['POST']) def GetEchoPost(): postText = request.form['text'] return "Echo Post:"+postText
To the data send can be accessed by using the “request” object.
A function may want to return more than just a simple string. To turn your results into a JSON object simply use the provided function “jsonify()”:
@app.route(register("/JSON")) def GetJSON(): data = [] data.append("element 1") data.append("element 2") return jsonify(elements=data)
This will return:
{"elements": ["element 1", "element 2"]}
For more information on Flask take a look at the quickstart introduction and the full API.
The Environment
There are already some useful functions defined that can be used to specify the behavior of your route. These functions can be wrapped around your route by applying the decorator using the “@” symbol.
- @app.route will create a new route. If you also use “register” this will add this new route to the list returned by /help.
- @ErrorHandling will handle exceptions automatically.
- @RequireLogin will make sure that this request will only answer to a registered user.
- @RequiredAdmin will make sure only admins can access this route.
- @Gzipped will send a zip file if the content fits.
To get data and to start actions you have to communicate with the host – the actual Team Render Server application. Different libraries are accessible through these objects:
- jobs: access jobs including assets and results.
- network: manages the machines in your network.
- users: let’s you access user information and edit their settings.
- util: offers a function to create a JPEG from a BaseBitmap.
- settings: manages a few predefined constants.
You find the source code of these objects in \resource\modules\teamrender\webserver\core. Many functions will return a BaseContainer as a result. The IDs of the stored elements can be found in the lib_net.h header file.
Getting Custom Results
In this simple example I send a username to the server using a POST request. The server will then answer by sending the list of jobs that were created by that user:
@app.route(register("/jobsByUser"), methods=['POST']) @RequireLogin @ErrorHandling def GetJobsByUser(): username = request.form['username'] # this will return a list of BaseContainer objects foundJobs = jobs.GetJobsOrJob(session['useruuid'],0,0,0,0) #prepare array jobsFromUser = [] #search in jobs for jobs created by the given user for job in foundJobs: name = job[c4d.JOB_USER] if name == username: jobsFromUser.append(job) # prepare result result = {} result['jobs'] = jobsFromUser # add username for convenience result['user'] = username return jsonify(result)