To solve the given optimization problem, we first need to translate the natural language description into a symbolic representation. This involves defining variables for the quantities of wallets and purses produced, formulating the objective function that represents the total profit, and listing the constraints based on the time available for cutting and stitching.

Let's define:
- $x_1$ as the number of wallets produced
- $x_2$ as the number of purses produced

The symbolic representation of the problem is given by:

```json
{
  'sym_variables': [('x1', 'number of wallets'), ('x2', 'number of purses')],
  'objective_function': '50*x1 + 100*x2',
  'constraints': [
    '10*x1 + 15*x2 <= 500',  # Cutting time constraint
    '20*x1 + 30*x2 <= 600',  # Stitching time constraint
    'x1 >= 0',               # Non-negativity constraint for wallets
    'x2 >= 0'                # Non-negativity constraint for purses
  ]
}
```

This representation captures the essence of the problem: maximizing profit (`50*x1 + 100*x2`) under the constraints of available cutting and stitching time, and ensuring that the quantities of wallets and purses produced are non-negative.

To solve this linear programming problem using Gurobi in Python, we'll write the following code:

```python
from gurobipy import *

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

# Define variables
x1 = m.addVar(vtype=GRB.CONTINUOUS, name="wallets", lb=0)
x2 = m.addVar(vtype=GRB.CONTINUOUS, name="purses", lb=0)

# Set the objective function
m.setObjective(50*x1 + 100*x2, GRB.MAXIMIZE)

# Add constraints
m.addConstr(10*x1 + 15*x2 <= 500, "cutting_time")
m.addConstr(20*x1 + 30*x2 <= 600, "stitching_time")

# Optimize the model
m.optimize()

# Print the solution
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Number of wallets: {x1.x}")
    print(f"Number of purses: {x2.x}")
    print(f"Total profit: {m.objVal}")
else:
    print("No optimal solution found")
```