This is an experimental toolkit designed for the workshop at 未來智慧工場 (Atelier Future) of National Cheng Kung University (NCKU) in 2023. The toolkit consists of an API server and examples, and we assume that XR scenes are created on the STYLY platform using Unity, PlayMaker, and STYLY Plugin for Unity. This toolkit allows you to build a common reference base between scenes, bringing consistency to the XR experience.
- No Black Boxes: Remember the first time you wrote a "Hello, World!" in Python? That sense of achievement you felt? We believe in keeping things transparent. If you have the basics of Python under your belt, you'll be able to dive into our code, understand it, and even modify it to your heart's content. No mysteries here!
- Minimalism at its Best: Our API server is like a blank canvas. We provide just the essential functions to get you started. But guess what? You're the artist here! Add features, modify existing ones, and paint your masterpiece. Our tool grows as you grow.
- Abundant Documentation: Ever felt lost while using a tool? We've been there. That's why we've put together a comprehensive guide to help you out. Check out
api_documentation.md
for detailed insights and instructions. It's like having a friendly guide by your side!
- In our system, every user has a specific role. The roles are:
- Designer: Responsible for creating and managing locations, items, and tags.
- Player: Interacts with items, acquires them, and communicates using message boards.
- Sensor: Updates the status of items based on physical-world inputs.
- Actuator: Acts upon or responds to item statuses.
- Each role has a unique API key, ensuring secure and role-specific interactions.
- Every item is associated with a location. Locations are of two types:
INDOOR
: For items inside buildings or confined spaces.OUTDOOR
: For items in open areas or natural environments.
- For items in an
INDOOR
location, we specify their position using three coordinates: x, y, and z. - For items in an
OUTDOOR
location, we use geographical coordinates: latitude (north-south position) and longitude (east-west position).
- Items are objects or entities you can interact with. Each item has:
- Name: An identifier or label for the item.
- Owner: Indicates who currently possesses the item. By default, items belong to
PUBLIC_DOMAIN
, meaning they are available for all. Once a player acquires an item, its ownership changes toA_PLAYER
. - Type: Describes the category of the item.
- Coordinates: Specifies the item's position in its location.
- Tags (optional): Keywords to help categorize and filter items.
- Attributes (optional): Additional properties or details about the item.
- Tags are like labels. They help in organizing and finding items based on specific categories or properties. For example, if you're searching for a specific type of item, you can use tags to filter and find them quickly.
In the development and deployment of this API, we utilized a combination of modern technologies and platforms to ensure robustness, scalability, and ease of use. Here's an overview:
- What it is: Flask is a lightweight web framework written in Python. It's designed for quick and easy development of web applications.
- Role in this API: Flask serves as the backbone of our API server. We use it to define endpoints, handle requests, and send responses to users.
- What it is: Cloud Firestore is a flexible, scalable, and NoSQL cloud database from Google Firebase. It allows for real-time data synchronization and offers robust querying capabilities.
- Role in this API: Cloud Firestore acts as our primary database. We store details like locations, items, and tags here. Its real-time capabilities ensure that users always interact with the most up-to-date data.
- What it is: Render is a Platform as a Service (PaaS) that offers cloud computing services. It simplifies the process of deploying, scaling, and managing applications and databases.
- Role in this API: We use Render to host our Flask-based API server. It ensures that the API is always available and can handle multiple requests simultaneously. Render's infrastructure also ensures smooth scaling as the number of users grows.
This sequence diagram provides a step-by-step representation of setting up a server using Cloud Firestore as a database and Render as a Platform-as-a-Service (PaaS). The flow captures interactions between the developer, user, Render, Cloud Firestore, and GitHub repository, highlighting the key actions from project creation to deploying updates.
sequenceDiagram
actor User
actor Developer
participant Render
participant Firestore as Cloud Firestore
participant GitHub as GitHub Repository
Developer->>Firestore: Create new project
Developer->>Firestore: Set up new database
Firestore-->>Developer: Provide private key
Developer->>+GitHub: Request to fork repository
GitHub->>GitHub: Execute fork
GitHub-->>-Developer: Share forked repository details
Developer->>Render: Initiate new project
Developer->>Render: Configure using repository details, private key, etc.
Developer->>Render: Click "Create Web Service" button
Render->>GitHub: Fetch repository content
GitHub-->>Render: Send repository content
Render->>Render: Execute build
loop For every endpoint call
User->>+Render: Send request
Render->>+Firestore: Forward request
Firestore-->>-Render: Return response
Render-->>-User: Send response
end
loop For every push to the GitHub repository
Developer->>GitHub: Push updates
GitHub->>GitHub: Commit changes
GitHub-->>Render: Notify about update
Render->>GitHub: Fetch updated content
GitHub-->>Render: Send updated content
Render->>Render: Execute build
end
- Navigate to the Firebase console: https://console.firebase.google.com/.
- Click
Add project
and follow follow the on-screen instructions to create a Firebase project (you may uncheck the toggle button forEnable Google Analytics for this project
to disable Google Analytics). - Once your project is ready, click the
Continue
button, then navigate to theCloud Firestore
section. - Look for
Cloud Firestore
and follow the database creation workflow.- Choose
Start in production mode
. - Choose a suitable
Cloud Firestore location
(e.g., asia-southeast1: Singapore).
- Choose
- Once finished, navigate to the ⚙️ button on the top left →
Project settings
→Service accounts
. - Click the
Generate new private key
button, read the warning, and then click theGenerate key
button to generate a new key (a JSON file) and download the key to your local machine. - IMPORTANT: Keep the JSON file in a safe place. You can’t reissue the key; if lost, you'll need to generate a new one.
- Navigate to https://github.com/kotobuki/Toolkit-for-Collaborative-XR/.
- Fork the project.
- Navigate to https://render.com/ and create an account (recommended to use a GitHub account).
- Click on the
New +
button on the top-right and chooseWeb Service
. - Click the
Connect account
button under the GitHub icon. - Choose
Only select repositories
for theRepository access
and select the forked repository. - Choose
Standard
for theInstance Type
. - Click on the
Advanced
button.- Navigate to the
Start Command
section and setgunicorn server:app
as the start command. - Navigate to the
Environment Variables
section and set the following environment variable keys with their respective values:API_KEY_DESIGNER
:abcdefgh00000000
API_KEY_PLAYER
:abcdefgh00000001
API_KEY_SENSOR
:abcdefgh00000002
API_KEY_ACTUATOR
:abcdefgh00000003
SERVICE_ACCOUNT_KEY_JSON
: Copy and paste the content of the generated key file. Ensure this content remains confidential.
- Navigate to the
- Click on the
Create Web Service
button to start deploying.
This guide provides a step-by-step procedure for setting up and testing the API server on your local machine. Whether you are a developer or just someone curious to run the API server, by following these steps, you will have a locally running instance of the server. This is especially useful for debugging, feature development, or simply understanding the inner workings of the API.
-
Clone the repository.
-
Open a terminal in the repository directory.
-
Create a virtual environment and activate the environment.
python3 -m venv .venv . .venv/bin/activate
-
Install the required dependencies. Additionally, if you don't have
jq
installed and you're on macOS with Homebrew, you can install it as shown below. For other platforms, please consult thejq
official documentation for installation instructions.pip install -r requirements.txt brew install jq
-
Export the environment variables. Remember to replace
service-account-key.json
with the path to your previously downloaded Firebase key file.export API_KEY_DESIGNER=abcdefgh00000000 export API_KEY_PLAYER=abcdefgh00000001 export API_KEY_SENSOR=abcdefgh00000002 export API_KEY_ACTUATOR=abcdefgh00000003 SERVICE_ACCOUNT_KEY_JSON=$(jq -c . service-account-key.json) export SERVICE_ACCOUNT_KEY_JSON
-
Run the server app in the environment.
gunicorn server:app
-
After running the server, check the terminal for a message indicating the listening address. This address (for example,
http://127.0.0.1:8000
) is the base URL you'll use to access the API.[INFO] Listening at: http://127.0.0.1:8000
python docstring_to_md.py server.py
python docstring_to_test_client.py server.py
- Open
test_client.html
in your web browser. - Fill in the Base URL and API Key fields.
- Choose a role from radio buttons (e.g., Designer).
- Choose an endpoint, fill in the parameters, and press the Submit button.
Install necessary packages and run the test script.
pip install numpy tqdm
python api_test.py {full_url_with_parameters}
If you choose the Starter
plan (512MB of RAM, 0.5 CPU core), use the following configuration. This configuration allows for two simultaneous connections.
gunicorn --workers 1 --threads 2 server:app
If you choose the Standard
plan (2 GB of RAM, 1 CPU core), use the following configuration. This configuration supports 6 simultaneous connections. You can experiment by increasing the number of threads to 3, which would allow for 9 simultaneous connections. However, always monitor the memory and CPU usage via the dashboard.
gunicorn --workers 3 --threads 2 server:app