To solve this optimization problem, we first need to define the decision variables and the objective function. Let's denote:

- \(G\) as the number of glass chandeliers produced.
- \(B\) as the number of brass chandeliers produced.

The profit per glass chandelier is $400, and the profit per brass chandelier is $300. Therefore, the total profit can be represented by the objective function:
\[ \text{Maximize:} \quad 400G + 300B \]

We have two main constraints based on the time available for crafting and installation:

1. **Crafting Time Constraint**: Each glass chandelier takes 2 hours to craft, and each brass chandelier takes 1.5 hours to craft. The company has 750 hours available for crafting. Thus, the constraint is:
\[ 2G + 1.5B \leq 750 \]

2. **Installation Time Constraint**: Each glass chandelier takes 1 hour to install, and each brass chandelier takes 0.75 hours to install. The company has 500 hours available for installation. Thus, the constraint is:
\[ G + 0.75B \leq 500 \]

Additionally, we have non-negativity constraints since the number of chandeliers cannot be negative:
\[ G \geq 0, B \geq 0 \]

Given these constraints and the objective function, we can now formulate this problem in Gurobi Python code:

```python
from gurobipy import *

# Create a new model
m = Model("Chandelier_Optimization")

# Define variables
G = m.addVar(vtype=GRB.CONTINUOUS, name="Glass_Chandeliers")
B = m.addVar(vtype=GRB.CONTINUOUS, name="Brass_Chandeliers")

# Set the objective function: Maximize profit
m.setObjective(400*G + 300*B, GRB.MAXIMIZE)

# Add constraints
m.addConstr(2*G + 1.5*B <= 750, "Crafting_Time_Constraint")
m.addConstr(G + 0.75*B <= 500, "Installation_Time_Constraint")

# Optimize the model
m.optimize()

# Print the results
if m.status == GRB.OPTIMAL:
    print(f"Optimal solution found: Produce {G.x} glass chandeliers and {B.x} brass chandeliers.")
    print(f"Maximum profit: ${400*G.x + 300*B.x}")
else:
    print("No optimal solution found. The model is either infeasible or unbounded.")

```